赞
踩
是不是试了很多次都没有达到自己想要的效果呢?
没关系,看到这你就已经有收获了
光说不练歪把子
package socket_study03; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.CopyOnWriteArrayList; /** * 服务端最终版 * 1.多线程 * 2.代码封装 * * 功能: 群聊、私聊实现 * * 私聊格式说明:@xxx:msg * * @author 放牛娃学编程(公众号) * */ public class Server { //存放客户端的容器 private static CopyOnWriteArrayList<Channel> all = new CopyOnWriteArrayList<Channel>(); //一个channel就代表一个客户端(将其封装成一个类) static class Channel implements Runnable{ private DataOutputStream dos; private DataInputStream dis; private boolean flag; private String name; private Socket socket; //构造器,用于数据初始化 public Channel(Socket socket) { this.socket = socket; flag = true; try { dis = new DataInputStream(socket.getInputStream()); dos = new DataOutputStream(socket.getOutputStream()); //获取聊天昵称(也就是客户端发送的备注) this.name = receive(); //当客户加入聊天室后,发送欢迎信息 this.send("欢迎"+name+"进入到越撸越秃群聊中"); //给其它成员发"某某"加入到越撸越秃群聊中" this.sendOthers(name+"加入到越撸越秃群聊中", true); } catch(IOException e) { this.flag = false; this.release(); } } //接收消息 public String receive() { String msg = ""; try { msg = dis.readUTF(); } catch (IOException e) { // TODO Auto-generated catch block release(); } return msg; } //发送消息(发给自己) public void send(String msg) { if(!msg.equals("")) { try { dos.writeUTF(msg); dos.flush(); } catch (IOException e) { // TODO Auto-generated catch block release(); } } } /** * 1.群聊、发给除了自己以外的人 * 2.私聊、规定数据格式@xxx:msg * @param msg * @param isSys, 用来区分是否是系统消息,true为是,反之不是 */ public void sendOthers(String msg, boolean isSys) { boolean isPrivate = msg.startsWith("@"); if(isPrivate) //私聊消息 { //获取冒号下标(便于截取名字) int index = msg.indexOf(":"); //截取名字(@人的备注) String targetName = msg.substring(1, index); //截取@的信息 msg = msg.substring(index + 1); //遍历容器,找到要@的人 for(Channel other: all) { if(other.name.equals(targetName)) { other.send(this.name + "敲敲对你说:"+ msg); //私聊 break; //目标找到,发完私聊消息退出遍历 } } } else //不是私聊信息 { //发给其它人,除自己以外,其实就是群聊 for(Channel other:all) { if(other != this) //this就代表自己,本通道 { if(!isSys) { other.send(this.name+"说:"+msg); //不是系统消息 } else { other.send(msg); //系统消息 } } } } } //释放资源 public void release() { this.flag = false; Utils.release(dos, dis, socket); //退出 all.remove(this); sendOthers(this.name+"离开了该群聊……", true); } //线程体 @Override public void run() { // TODO Auto-generated method stub while(flag) { //接收消息 String msg = receive(); //群聊发消息(类似群发) if(!msg.equals("")) { sendOthers(msg, false); //不是系统消息 } } } } public static void main(String[] args) throws IOException { // TODO Auto-generated method stub System.out.println("-----这是服务端----------"); //获取ServerSocket管道 ServerSocket sSocket = new ServerSocket(9898); while(true) { //获取客户端的socket Socket client = sSocket.accept(); System.out.println("一个客户端连接成功"); Channel channel = new Channel(client); //将每个客户端添加到容器中,进行统一管理 all.add(channel); //启动线程 new Thread(channel).start(); } } }
如果遇到问题,没关系,多去折腾就完事了,也欢迎小伙伴们留言交流学习。
最后有兴趣一起交流的,可以关注我的公众号:这里你能够学到很实用的技巧,不是常用的我不说,公众号回复提取码即可获取以下学习资料啦啦啦啦,喜欢就拿去吧!!
(链接时常会失效,若出现此类情况,可以加我微信:17722328325(加时请备注:学习资料))
Java web从入门到精通电子书
Python机器学习电子书
Python400集(北京尚学堂)
JavaScript项目案例、经典面试题
Java300集(入门、精通)
Java后端培训机构录集(同事培训内部提供)
IO流文档
JavaEE面试题及其参考答案文档
JavaSE面试题及其参考答案文档
java多线程技术文档
java网络编程文档
7~11都是之前同学花钱买来备战找实习的,需要的我也分享出去了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。