java在线聊天项目1.0版 异常处理——开启多个客户端,关闭一个客户端后,在其他客户端中再发出信息会出现异常的处理...
异常一
只开启一个客户端,输入信息后关闭,客户端出现如下异常
根据异常说明 ChatClientFrame客户端117行
提示原因是Socket关闭
分析原因
客户端代码
while (connected) {
String str = dis.readUTF();
当窗口关闭后,Socket已经关闭,读的操作还在继续
处理这个异常,代码如下
catch (SocketException e) {
System.out.println("a client has been closed!");
}
同时,
服务端出现下边异常
解决异常
catch(EOFException e) {
System.out.println("a client has been closed,can't read message from it.");
}
异常二
开启多个客户端,关闭一个客户端后,在其他客户端中再发出信息,服务器端会出现异常
这个问题是由
for(int i=0;i<clients.size();i++) {
Client c=clients.get(i);
c.send(str);
}
此处产生逻辑bug,当一个客户端被关闭之后,这个客户端还在clients集合当中,这个被关闭的客户端还要再执行send(str)发送信息
造成
private void send(String str) {
try {
dos.writeUTF(str);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
}
产生异常
解决异常,在集合中把这个客户端删除掉
catch(SocketException e) {
clients.remove(this);
}
服务器端完整代码如下:
package com.swift;import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.util.ArrayList; import java.util.List;public class ChatServer {boolean started = false;ServerSocket ss = null;Socket s = null;List<Client> clients=new ArrayList<Client>(); public static void main(String[] args) {new ChatServer().fun();}private void fun() {try {ss = new ServerSocket(8888);started = true;} catch (BindException e) {System.out.println("端口使用中......");} catch (IOException e1) {e1.printStackTrace();}try {while (started) {s = ss.accept();System.out.println("a client connected success");Client c = new Client(s);new Thread(c).start();clients.add(c);}} catch (EOFException e) {System.out.println("client has closed.");} catch (Exception e) {e.printStackTrace();} finally {try {ss.close();} catch (IOException e) {// TODO Auto-generated catch block e.printStackTrace();}}}class Client implements Runnable {private Socket s;private DataInputStream dis;private DataOutputStream dos;private boolean connected = false;public Client(Socket s) {this.s = s;try {this.dis = new DataInputStream(s.getInputStream());this.dos = new DataOutputStream(s.getOutputStream());connected = true;} catch (IOException e) {// TODO Auto-generated catch block e.printStackTrace();}}private void send(String str) {try {dos.writeUTF(str);} catch(SocketException e) {clients.remove(this);} catch (IOException e) {e.printStackTrace();};}@Overridepublic void run() {try {//注意:要包括while循环,如果try在while循环里,则出现socket closed异常while (connected) {String str = dis.readUTF();System.out.println(str);for(int i=0;i<clients.size();i++) {Client c=clients.get(i);c.send(str);}// for(Iterator<Client> it=clients.iterator();it.hasNext();) { // Client c=it.next();//方法二,不可取,有同步锁 // c.send(str); // }// Iterator<Client> it=clients.iterator(); // while(it.hasNext()) { // Client c=it.next();//方法三,不可取,有同步锁,修改需要加锁(此时没修改) // c.send(str); // } }} catch(EOFException e) {System.out.println("a client has been closed,can't read message from it.");} catch (IOException e) {e.printStackTrace();} finally {if (dis != null) {try {dis.close();} catch (IOException e) {e.printStackTrace();}}if(dos!=null) {try {dos.close();} catch (IOException e) {e.printStackTrace();}}if (s != null) {try {s.close();} catch (IOException e) {e.printStackTrace();}}}}} }
客户端完整代码如下:
package com.swift;import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ConnectException; import java.net.Socket; import java.net.SocketException;import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField;public class ChatClientFrame extends JFrame {private static final long serialVersionUID = -118470059355655240L;Socket s;DataOutputStream dos;DataInputStream dis;private boolean connected = false;JLabel label_shang = new JLabel();JLabel label_xia = new JLabel();JTextField tf = new JTextField(38);JTextArea ta = new JTextArea(15, 50);JButton button = new JButton();public ChatClientFrame() {setBounds(200, 200, 500, 400);setTitle("客户端聊天工具 —— 1.0");// 对窗口进行大的布局,分为三行一列,在pBasic面板上添加三个面板shang zhong xiaJPanel pBasic = new JPanel();pBasic.setLayout(new BorderLayout());// 不设置默认也是这种布局模式setContentPane(pBasic);// 把面板放在窗口上,不记得用this.关键字JPanel shang = new JPanel();JPanel zhong = new JPanel();JPanel xia = new JPanel();// 设置JPanel面板的大小shang.setSize(470, 25);zhong.setSize(470, 180);xia.setSize(470, 40);pBasic.add(shang, BorderLayout.NORTH);pBasic.add(zhong, BorderLayout.CENTER);pBasic.add(xia, BorderLayout.SOUTH);shang.setBackground(Color.red);zhong.setBackground(Color.yellow);xia.setBackground(Color.blue);label_shang.setText("聊天记录");shang.add(label_shang);ta.setLineWrap(true);// 自动换行JScrollPane scroll = new JScrollPane(ta);// 增加滚动条,以便不增加行数 zhong.add(scroll);label_xia.setText("输入信息");xia.add(label_xia, BorderLayout.WEST);/** 增加功能,窗口监听事件,窗口打开时设置光标焦点在tf文本域中*/this.addWindowListener(new WindowAdapter() {@Overridepublic void windowOpened(WindowEvent e) {tf.requestFocus();}});xia.add(tf, BorderLayout.CENTER);button.setText("发送");xia.add(button, BorderLayout.EAST);button.addActionListener(new ShareListener());tf.addActionListener(new ShareListener());pack();this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {disconnect();System.exit(0);}});setVisible(true);// 创建窗体直接调用连接服务器 connect();Thread t=new Thread(new ReceiveThread());t.start();}class ShareListener implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {String tfText1 = tf.getText();tf.setText("");// 当回车或发送按钮时,tfText发送到服务器try {dos.writeUTF(tfText1);dos.flush();} catch (IOException e1) {e1.printStackTrace();}}}class ReceiveThread implements Runnable {@Overridepublic void run() {try {while (connected) {String str = dis.readUTF();System.out.println(str);ta.setText(ta.getText()+str+"\r\n");}} catch (SocketException e) {System.out.println("a client has been closed!");} catch (IOException e) {e.printStackTrace();}}}public void connect() {try {s = new Socket("127.0.0.1", 8888);System.out.println("connected!");connected=true;dos = new DataOutputStream(s.getOutputStream());dis = new DataInputStream(s.getInputStream());} catch (ConnectException e) {System.out.println("服务端异常.........");System.out.println("请确认服务端是否开启.........");} catch (IOException e) {e.printStackTrace();}}public void disconnect() {try {if (dos != null)dos.close();if(dis !=null)dis.close();if (s != null)s.close();} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {new ChatClientFrame();}}
转载于:https://www.cnblogs.com/qingyundian/p/7995070.html
java在线聊天项目1.0版 异常处理——开启多个客户端,关闭一个客户端后,在其他客户端中再发出信息会出现异常的处理...相关推荐
- java在线聊天项目ppt_基于JavaEE的在线聊天聊天.ppt
基于JavaEE的在线聊天聊天.ppt 聊城大学论文答辩,指导教师,学生姓名,年 月,基于JavaEE的在线聊天聊天 系统的设计与实现,论文提纲,,选题背景.研究内容,1,JavaEE技术介绍,主要创 ...
- java在线聊天项目0.6版 解决客户端关闭后异常问题 dis.readUTF()循环读取已关闭的socket...
服务端对try catch finally重新进行了定义,当发生异常,主动提示,或关闭出现异常的socket 服务器端代码修改如下: package com.swift;import java.io. ...
- java在线聊天项目0.4版本 制作服务端接收连接,客户端连接功能 新增客户端窗口打开时光标指向下边文本域功能,使用WindowListener监听WindowAdapter...
建一个服务端类ChatServer,用于设置端口接收连接 package com.swift;import java.io.IOException; import java.net.ServerSoc ...
- java在线聊天项目 使用SWT快速制作登录窗口,可视化窗口Design 更换窗口默认皮肤(切换Swing自带的几种皮肤如矩形带圆角)...
SWT成功激活后 new一个JDialog 调整到Design视图 默认的视图模式是BorderLayout,无论你怎么拖拽,只能放到东西南北中的位置上 所以,我们把视图模式调整为AbsoluteLa ...
- 转载:仿QQ聊天软件2.0版
仿QQ聊天软件2.0版 这是大神的地址:牟尼的专栏 http://blog.csdn.net/u012027907 详细的过程本人没看,但是看见他的实现效果,相当诱人! 上次课设做了Java版 ...
- PHP在线考试系统4.0版本源码电脑+手机端
PHP在线考试系统的功能与优点: 1.强化训练测验,对知识点进行单独联系 : 2.随机组卷练习,系统自动抽取题目进行练习 : 3.手工组卷联系,通过教师平台手工组卷形成考卷进行模拟练习 : 4.支持主 ...
- javaweb:在线聊天网站(框架版)
之前写过一次在线聊天网站,不过那次是无框架版的,这次用框架构建网站,基本功能和上次差不多 涉及知识 java spring(4.3.5):spring.spring MVC hibernate boo ...
- Java在线教育项目 第一天项目介绍和工程搭建
第一章 项目介绍和工程搭建 学习目标 熟悉移动端应用系统的架构设计 熟悉大型软件系统设计中的各种图形结构 熟悉数据库分库分表设计技巧 熟悉Spring boot2.0+JavaConfig项目封装配置 ...
- 微信支付开发,基于SpringBoot+Vue架构的Java在线支付项目
目录 前言 1. 支付安全 1.1 对称加密和非对称加密 1.2 身份认证 1.3 摘要算法 1.4 数字签名和数字证书 2. 项目初期 2.1 构建测试 2.2 引入Swagger 2.3 引入lo ...
- 基于Vite + Vue3 + Typescript 实现在线聊天项目
前言 本项目是本人的毕业设计,在校的时候看着同学都都开始一步一步的开始准备毕设了,刚好那段时间正在了解websocket,于是有了个想法,毕设能不能做一个在线聊天的系统. 前端技术用到了 Vue3 + ...
最新文章
- aggr代码 cellranger_单细胞转录组测序数据分析流程-数据预处理
- jflash合并stm32f103之bin文件及hex文件
- 一款让你“乐词不疲”的背单词神器
- 基于hi-nginx的web开发(python篇)——utf-8编码
- 高效的企业测试–测试框架(5/6)
- D3 datumdata
- SpringCloud Config详解
- 阿里云语音识别模型端核心技术选讲
- primefaces教程_Primefaces Spring和Hibernate集成示例教程
- linux源码安装php,nginx配置php
- 群体智能算法之蝙蝠算法
- 盘点40种常用的芯片封装技术
- iText5实现Java生成PDF文件完整版
- 键盘表和ASCII码表
- CacheCloud安装配置
- 阿里云跨云迁移工具案例实践:华为云迁移到阿里云
- 美国国家机器人计划2.0部分项目简介
- 计算性和复杂度理论2
- 运维简历怎么写项目描述_职场小白怎么写简历?一份好简历=成功一半
- 数据库系统概论复习提纲
热门文章
- 3.6 Spark安装与体验
- Spark:Spark 编程模型及快速入门
- 【论文阅读】Efficient Net
- 伪标记是一种简单的半监督学习方法
- 新型消防机器人作文_说一说消防机器人
- python与r语言处理excel数据_【R语言】批量读取Excel数据并合并(升级版)
- tensorflow如何微调时如何只训练后两层_XLNet只存在于论文?都替你封装好了还不来用!...
- 关于sophus模板类需要注意的情况(error: missing template arguments before ‘SO3_R’)
- Linux字体最好看的发行版,如何给任意一款 Linux 发行版添加漂亮的字体
- 《永不放弃-马云给创业者的24堂课》— 综合素质提升书籍