一、概述

1.目标:在上一个版本非线程的聊天系统中,出于要不断监听接收新client和接收client发出的信息,把accept()和DataInputStream.readUTF()分别写在了while()死循环里,由于俩方法都是阻塞性方法,所以一方阻塞,另一方永远得不到执行,所以,在上述代码中,只能监听第一个client的发送信息,新的client永远连接不上。

2.思路:

(1)把socet.accept()接收线程和DataInputStream.readUTF()的处理分开,把前者交给server端的处理,server端把接收到的clent封装到线程里,把DataInputStream.readUTF()的逻辑交给线程处理。

(2)采用异步IO

二、代码

1.ChatServer.java

import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;public class ChatServer{private ServerSocket ss = null;private boolean started = false;public static void main(String[] args) {new ChatServer().start();}public void start(){try {ss = new ServerSocket(8888);started = true;} catch (IOException e1) {e1.printStackTrace();}try {while(started){//!!!!!注意accept()是阻塞性方法,当被readUTF()阻塞时它不会被执行Socket s = ss.accept();
System.out.println("a client connect------"+s);new Thread(new Client(s)).start();}} catch (EOFException e) {System.out.println("客户端已关闭!");} catch (IOException e) {e.printStackTrace();}finally{try {//if(dis != null ) dis.close();//if(s != null ) s.close();if(ss != null ) ss.close();} catch (Exception e) {e.printStackTrace();}}}private class Client implements Runnable{private Socket s;private DataInputStream dis = null;boolean bConnect = false;public Client(Socket s) {super();this.s = s;try {dis = new DataInputStream(s.getInputStream());bConnect = true;} catch (IOException e) {e.printStackTrace();}}@Overridepublic void run() {try {while(bConnect){//!!!!!注意readUTF()是阻塞性方法System.out.println(dis.readUTF());}} catch (EOFException e) {System.out.println("客户端已关闭!");} catch (IOException e) {e.printStackTrace();}finally{try {if(dis != null ) dis.close();if(s != null ) s.close();} catch (Exception e) {e.printStackTrace();}}}}}

  

2.ChatClient.java

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;public class ChatClient extends Frame{private TextField tfText;private TextArea taContent;
//  private Button btnSend;private Socket socket;private DataOutputStream dos;public void launchFrame(){addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {disconnect();System.exit(0);}});tfText = new TextField();taContent = new TextArea();
//      btnSend = new Button("发送");
//
//      btnSend.addActionListener(new ActionListener() {
//          @Override
//          public void actionPerformed(ActionEvent e) {
//              //taContent.setText(taContent.getText()+"\n\r"+tfText.getText());
//              //tfText.setText("");
//              try {
//                  DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
//                  dos.writeUTF(tfText.getText());
//                  dos.close();
//                  socket.close();
//              } catch (IOException e1) {
//                  e1.printStackTrace();
//              }
//          }
//      });tfText.addActionListener(new TFListener());add(taContent,BorderLayout.NORTH);add(tfText,BorderLayout.CENTER);
//      add(btnSend,BorderLayout.SOUTH);setLocation(300, 100);pack();setVisible(true);connect("localhost", 8888);}//当调用了此方法,会自动把成员变量给socket连接上serverpublic void  connect(String address, int port){try {socket = new Socket(address, port);dos = new DataOutputStream(socket.getOutputStream());} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}//退出时释放资源public void disconnect(){try {if(dos != null ) dos.close();if(socket != null ) socket.close();} catch (IOException e) {e.printStackTrace();}}class TFListener implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {taContent.setText(taContent.getText().trim()+"\n\r"+tfText.getText());try {dos.writeUTF(tfText.getText());dos.flush();tfText.setText("");//dos.close();//socket.close();} catch (IOException e1) {e1.printStackTrace();}}}public static void main(String[] args) {new ChatClient().launchFrame();}
}

  

三、运行结果

转载于:https://www.cnblogs.com/shamgod/p/4612142.html

Java-在线聊天系统-线程相关推荐

  1. 基于SpringBoot开发的Java web在线聊天系统,即时通讯通信系统,基于IDEA开发

    目录 简介 主要实现的功能有: 主要功能截图 温馨提示 简介 今天发布的是一款由Springboot+MySQL+SSM实现的Java web在线聊天系统,适合大家在网上聊天,加好友等操作,极大的方便 ...

  2. java 写入txt_Java线程转储的8个选项

    线程转储是诊断CPU尖峰,死锁,内存问题,无响应的应用程序,较差的响应时间以及其他系统问题的重要工件. 有很多很棒的在线线程转储分析工具,可以分析和发现问题.但是对于那些工具,您需要提供适当的线程转储 ...

  3. java在线聊天项目ppt_基于JavaEE的在线聊天聊天.ppt

    基于JavaEE的在线聊天聊天.ppt 聊城大学论文答辩,指导教师,学生姓名,年 月,基于JavaEE的在线聊天聊天 系统的设计与实现,论文提纲,,选题背景.研究内容,1,JavaEE技术介绍,主要创 ...

  4. 基于Springboot+vue的在线聊天系统

    [辰兮要努力]:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行! 博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端.后台.数据 ...

  5. 聊天系统服务器端类图怎么画,在线聊天系统的设计与实现.docx

    PAGE 在线聊天系统的设计与实现 本科毕业设计 目录TOC \o "1-3" \h \u 目录 1 前 言 1 2. 需求分析 2 2.1 系统运行环境需求 2 2.2 模块功能 ...

  6. 基于C语言实现的多人在线聊天系统(客户端和服务端源码)

    资源下载地址:https://download.csdn.net/download/sheziqiong/85768602 资源下载地址:https://download.csdn.net/downl ...

  7. jsp实现在线聊天系统

    在线聊天系统 大概介绍 就是一个在线聊天平台. 功能 用户登陆.注册 聊天室的创建.查看.加入 聊天信息的查询.发布 聊天室人数限制 聊天上线提示和下线提示 涉及相关技术 表单开发 内置对象 jdbc ...

  8. 面试官:Java如何绑定线程到指定CPU上执行?

    不知道你是啥感觉,但是我第一次看到这个问题的时候,我是懵逼的. 而且它还是一个面试题. 我懵逼倒不是因为我不知道答案,而是恰好我之前在非常机缘巧合的情况下知道了答案. 我感觉非常的冷门,作为一个考察候 ...

  9. Java常用四大线程池用法以及ThreadPoolExecutor详解

    2019独角兽企业重金招聘Python工程师标准>>> 为什么用线程池? 1.创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处-理效率 2.线程并发数量过多 ...

  10. 基于SSH的在线音乐点评网站-java在线音乐点评网站

    基于SSH的在线音乐点评网站-java在线音乐点评网站 开发环境:Eclipse for J2EE,MYSQL5.1,JDK1.7,Tomcat 7 首页主要展示一些最新的音乐专辑. (1)用户注册: ...

最新文章

  1. Elasticsearch性能优化实战指南
  2. VMware出现“该虚拟机似乎正在使用中 请获取所有权”
  3. 六大重点工程构筑兰州大数据产业
  4. python爬虫实战-python爬虫实战一:分析豆瓣中最新电影的影评
  5. 一种实现(无须root)手机截屏方案
  6. 从万物互联到万物智联,物联网的下一个爆发点在哪里?
  7. 华为天才少年,竟然要我用充电宝打游戏!
  8. 网络管理员的爱情,不解释...
  9. 《Node.js区块链开发》
  10. Android studio断点调试(全在这里)
  11. fastjson 序列化 不包括转义字符_fastjson再次发现漏洞,可能发生OOM导致宕机
  12. 8.3 bert的蒸馏讲解 意境级
  13. C语言小案例_OA大典故障案例摘录【第1393篇】爱普生c5290 彩色喷墨打印机 打印横白道...
  14. 计算机网络工程教程:基于cisco路由器和交换机,计算机网络工程教程—基于cisco路由器和交换机教学课件作者陆魁军chap7思科路由器的高级功能.ppt...
  15. 综合布线系统在计算机信息系统中属于,计算机信息系统综合布线问题
  16. 程序人生,心态变化!
  17. burpSuit抓取app的数据包
  18. FFmpeg源码分析:sws_scale图像缩放与图像转换
  19. jmeter测试之参数Shar256加密
  20. 不是发生中断请求的条件_交通部:只需满足3个条件,汽车购置税可以返还,你满足条件吗?...

热门文章

  1. UIButton的resizableImageWithCapInsets使用解析
  2. windows下的wxWidgets环境配置
  3. MSSQL2005:“超时时间已到。在操作完成之前超时时间已过或服务器未响应”
  4. flex navigateToURL()页面跳转的例子
  5. Oracle 11.2.0.2 Patch 说明
  6. Linux系统编程四:串口编程,控制LED和蜂鸣器
  7. 清除子节点、创建子节点函数
  8. lsb_release -a 查询Linux系统版本
  9. [转载]针对IIS7以上的ASP.NET网站自定义错误页面与异常日志总结
  10. jsp中向数据库中插入当前时间的方法精确到秒