收获:1,加深了对多线程的一边一边的理解,可以将行为写成不同的类然后多线程

2,IO流的复习!

3,多线程中一边读取一边操作时容器最好(CopyOnWriteArrayList);

4,Tcp流程的熟悉;

5,封装!!!代码的复用以及整洁!!!

改进:1,注释

2,对其中更多内容的封装,比如消息等

/**
 * 聊天室服务端
 * 实现接受和发送消息
 * 私聊
 * @author 小帆敲代码
 *
 */
public class ChatServer {
 static CopyOnWriteArrayList<Channel> all=new CopyOnWriteArrayList();
 public static void main(String[] args) throws IOException {
  ServerSocket server=new ServerSocket(8888);
  while(true) {
  Socket client=server.accept();
  System.out.println("一个客户端已连接");
  //添加至系统容器
  Channel channel=new Channel(client);
  all.add(channel);
  new Thread(channel).start();
  }
 }
 static class Channel implements Runnable{
  private DataInputStream dis;
  private DataOutputStream dos;
  private boolean isRunning=true;
  private Socket client;
  private boolean isName;
  private String name;
  
  public Channel(Socket client) {
   isName=true;
   isRunning=true;
   this.client=client;
   try {
    dis=new DataInputStream(client.getInputStream());
    dos=new DataOutputStream(client.getOutputStream());
   } catch (IOException e) {
    release();
   }
  }
  //接受消息
  public String receive() {
   String msg="";
   try {
    msg=dis.readUTF();
   } catch (IOException e) {
    release();
   }
   return msg;
  }
  //发送消息
  public void send(String msg) {
   if(!msg.equals("")) {
    try {
     dos.writeUTF(msg);
     dos.flush();
    } catch (IOException e) {
     release();
    }
   }
  }
  //给别人发送消息
  public void sendOthers(String msg) {
   //私聊
   //获取名字和内容
   if(msg.startsWith("@"))
   {
   int idx=msg.indexOf(":");
   String othername=msg.substring(1, idx);
   msg=msg.substring(idx+1);
   for(Channel others:all) {
    if(others.getName().equals(othername))
     {
     others.send(this.name+"悄悄对你说:"+msg);
     break;
     }
   }
   }
   else if(!msg.equals("")) {
    for(Channel others:all) {
     if(others==this)
      this.send("我:"+msg);
     else
      others.send(this.name+":"+msg);
    }
   }
  }
  //释放资源
  public void release() {
   isRunning=false;
   Utils.close(dis,dos,client);
  }
  @Override
  public void run() {
   String msg;
   while(isRunning) {
    if(isName)
    {
     msg=receive();//读
     this.name=msg;
     isName=false;
    }
    else
    {
    msg=receive();//读
    sendOthers(msg);//写
    }
   }
   release();//释放资源
  }
  public String getName() {
   return this.name;
  }
}
}

/**
 * 客户端
 *
 * @author 小帆敲代码
 *
 */
public class ChatClient {
public static void main(String[] args) throws UnknownHostException, IOException {
  Socket client=new Socket("localhost",8888);
  
  new Thread(new Send(client)).start();
  new Thread(new Receive(client)).start();
 }
}
/**
 * 接收类
 * @author 小帆敲代码
 *
 */
public class Receive implements Runnable{
 private DataInputStream dis;
 private Socket client;
 private boolean isRunning;
 
 public Receive(Socket client) {
  isRunning=true;
  this.client=client;
  try {
   dis=new DataInputStream(client.getInputStream());
  } catch (IOException e) {
   System.out.println("==4==");
   release();
  }
 }
 private String receive() {
  try {
   return dis.readUTF();
  } catch (IOException e) {
   System.out.println("==5==");
   release();
  }
  return "";
 }
 @Override
 public void run() {
  while(isRunning) {
   String msg=receive();
   System.out.println(msg);
  }
  
 }
 public void release() {
  isRunning=false;
  Utils.close(dis,client);
 }
}
/**
 * 发送类
 * @author 小帆敲代码
 *
 */
public class Send implements Runnable{
 private BufferedReader console;
 private DataOutputStream dos;
 private Socket client;
 private boolean isRunning;
 private String name;
 
 public Send(Socket client) {
  isRunning=true;
  this.client=client;
  console=new BufferedReader(new InputStreamReader(System.in));
  try {
   System.out.println("请输入用户名:");
   this.name=console.readLine();
   System.out.println(name+"欢迎回来");
   dos=new DataOutputStream(client.getOutputStream());
   this.send(name);
  } catch (IOException e) {
   System.out.println("==1==");
   release();
  }
 }
/*
 * 约定格式:
 * 私聊:@xxx:msg
 */
 private void send(String msg) {
  if(msg!="") {
   try {
    dos.writeUTF(msg);
    dos.flush();
   } catch (IOException e) {
    System.out.println("==2==");
    release();
   }
  }
 }
 private String getStrFromConsole() {
  try {
   return console.readLine();
  } catch (IOException e) {
   System.out.println("==3==");
   release();
  }
  return "";
 }
 @Override
 public void run() {
  while(isRunning) {
   String msg=getStrFromConsole();
   send(msg);
  }
  
 }
 private void release() {
  isRunning=false;
  Utils.close(console,dos,client);
 }
}
/**
 * 工具类
 * @author 小帆敲代码
 *
 */
public class Utils {
 /**
  *释放资源
  */
 static void close(Closeable... targets) {
  for(Closeable target:targets) {
   try {
    if(target!=null)
     target.close();
   }catch(Exception e){
    
   }
  }
 }
}

Java TCP案例网络聊天室相关推荐

  1. 基于TCP的网络聊天室实现(C语言)

    基于TCP的网络聊天室实现(C语言) 一.网络聊天室的功能 二.网络聊天室的结果展示 三.实现思路及流程 四.代码及说明 1.LinkList.h 2.LinkList.c 3.client.c 4. ...

  2. 基于Java socket的网络聊天室的设计与实现

    目 录 摘要 I Abstract II 目 录 III 1 引言 1 2 网络聊天室的简介 2 2.1网络聊天室现状和发展 2 3 完成网络聊天室的技术以及环境 4 3.1 Java的介绍 4 3. ...

  3. Linux C/TCP多线程网络聊天室

    多线程TCP网络聊天室 我们都知道TCP是一种基于连接的传输协议,使用多线程来实现其实步骤很简单. 首先说明一下项目:服务端开启后,直接运行客户端可以加入聊天室,同时其他客户端可以接收到某某客户端进入 ...

  4. java大作业网络聊天室

    这个项目是我大一的java期末大作业,学习了一个学期的成果,编程能力不够,做的并不够好,写在这里记录一下自己的成长,也欢迎大家给出宝贵意见! 第一次写博客哟,请多多支持! 该篇博客写一个基于java的 ...

  5. QT学习:基于TCP的网络聊天室程序

    TCP与UDP的差别如图: 一.TCP工作原理 如下图所示,TCP能够为应用程序提供可靠的通信连接,使一台计算机发出的字节流无差错 地送达网络上的其他计算机.因此,对可靠性要求高的数据通信系统往往使用 ...

  6. java tcp多人聊天室

    TCP的多人聊天室 上次写了一个只能两个人通信的TCP,这次写了个可以多人聊天的,利用多线程实现. 设计模式: 服务端:首先运行服务器,然后启动一个专门处理客户端消息的线程,然后监听是否有客户端连接, ...

  7. 基于TCP的网络聊天室

    综合分析: 基于TCP的聊天室,支持多个用户同时登陆服务器进行聊天.(相当于群) socket编程,做一对多的通信,必然要用到多线程,保证多个客户端(并行)登陆服务器时同时进行聊天. 项目要求: 利用 ...

  8. Java WebSocket实现网络聊天室(群聊+私聊)

    WebChat聊天室 2018.02.26 源码地址早就贴了呀, 留邮箱不如自己下载 项目地址: https://github.com/Amayadream/WebChat 2017.01.11更新 ...

  9. 基于java TCP实现网络通信聊天室《建议收藏附完整源码》

  10. [NUAA]Python用UDP协议建立带有私聊功能的网络聊天室-建立聊天工具

    文章目录 前言 1.网络聊天室的基本架构是什么? 1.1 客户端和服务器的架构 1.2 通信协议的选择以及多线程通信 1.2.1 多线程通信 1.2.2 通信协议选择 1.3 前后端功能设计思路 1. ...

最新文章

  1. NYOJ 264 国王的魔镜
  2. 怎么给web 服务器 传文件,web文件传到服务器
  3. linux ssh基本
  4. mysql 服务器初始面膜_安全初始化MySql服务器
  5. 大数据项目实践:基于hadoop+spark+mongodb+mysql开发医院临床知识库系统
  6. C#使用ServiceController控制windows服务
  7. dg oracle 切换模式_谈谈dg切换涉及的概念:switchover和failover区别
  8. 亮点抢先看 | 旷视科技11篇 ICCV 2019 论文概览
  9. 正则表达式2--re方法--match()--search()
  10. 直接在线查看github里的jupyter notebook
  11. php中左右去电空格,PHP中ltrim与rtrim去除左右空格及特殊字符实例
  12. 转:XMPP协议、MQTT协议、HTTP协议、CoAP协议的基本比较
  13. 如何选择合适的地图注记手段
  14. 成绩录取系统c语言,一个学生成绩管系统C语言源代码.doc
  15. 数据库中“一对一”、“一对多”、“多对多”的判断方法
  16. 畅享9能改鸿蒙,华为畅享9 root教程_畅享9卡刷root包来获取root权限的方法
  17. 如何打开计算机无线功能灰色,计算机没有wifi,仅显示宽带连接. 右键单击灰色的无线网络连接图...
  18. swiper 仿淘宝详情页面 视频图片切换
  19. 编程之路第11天:解决此前截屏权限需要手动点击确认问题(打开双线程)
  20. 专插本 计算机基础与程序设计 2020届考生纯手敲 C语言与数据结构学习中遇到的所有问题都在这里了,建议直接三连

热门文章

  1. Win32程序和控制台应用程序的项目互转设置
  2. 第三十七章 springboot+docker(手动部署)
  3. bbs小项目整理(六)(消息发布)
  4. 从JimmyNews有感于互联网的传播能力
  5. android自定义多按钮点击事件监听事件吗,安卓(Android)动态创建多个按钮并添加监听事件...
  6. 拓端tecdat|R语言确定聚类的最佳簇数:3种聚类优化方法
  7. sama5做linux的sd卡启动u盘,windows中service.msc与regedit
  8. 飞思卡尔单片机c语言编程详解,飞思卡尔单片机PIT汇编编程(一)
  9. python如何去某一列的元素
  10. python求两个字符串之间最小子串