异常一

只开启一个客户端,输入信息后关闭,客户端出现如下异常

根据异常说明 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版 异常处理——开启多个客户端,关闭一个客户端后,在其他客户端中再发出信息会出现异常的处理...相关推荐

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

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

  2. java在线聊天项目0.6版 解决客户端关闭后异常问题 dis.readUTF()循环读取已关闭的socket...

    服务端对try catch finally重新进行了定义,当发生异常,主动提示,或关闭出现异常的socket 服务器端代码修改如下: package com.swift;import java.io. ...

  3. java在线聊天项目0.4版本 制作服务端接收连接,客户端连接功能 新增客户端窗口打开时光标指向下边文本域功能,使用WindowListener监听WindowAdapter...

    建一个服务端类ChatServer,用于设置端口接收连接 package com.swift;import java.io.IOException; import java.net.ServerSoc ...

  4. java在线聊天项目 使用SWT快速制作登录窗口,可视化窗口Design 更换窗口默认皮肤(切换Swing自带的几种皮肤如矩形带圆角)...

    SWT成功激活后 new一个JDialog 调整到Design视图 默认的视图模式是BorderLayout,无论你怎么拖拽,只能放到东西南北中的位置上 所以,我们把视图模式调整为AbsoluteLa ...

  5. 转载:仿QQ聊天软件2.0版

    仿QQ聊天软件2.0版 这是大神的地址:牟尼的专栏 http://blog.csdn.net/u012027907 详细的过程本人没看,但是看见他的实现效果,相当诱人!     上次课设做了Java版 ...

  6. PHP在线考试系统4.0版本源码电脑+手机端

    PHP在线考试系统的功能与优点: 1.强化训练测验,对知识点进行单独联系 : 2.随机组卷练习,系统自动抽取题目进行练习 : 3.手工组卷联系,通过教师平台手工组卷形成考卷进行模拟练习 : 4.支持主 ...

  7. javaweb:在线聊天网站(框架版)

    之前写过一次在线聊天网站,不过那次是无框架版的,这次用框架构建网站,基本功能和上次差不多 涉及知识 java spring(4.3.5):spring.spring MVC hibernate boo ...

  8. Java在线教育项目 第一天项目介绍和工程搭建

    第一章 项目介绍和工程搭建 学习目标 熟悉移动端应用系统的架构设计 熟悉大型软件系统设计中的各种图形结构 熟悉数据库分库分表设计技巧 熟悉Spring boot2.0+JavaConfig项目封装配置 ...

  9. 微信支付开发,基于SpringBoot+Vue架构的Java在线支付项目

    目录 前言 1. 支付安全 1.1 对称加密和非对称加密 1.2 身份认证 1.3 摘要算法 1.4 数字签名和数字证书 2. 项目初期 2.1 构建测试 2.2 引入Swagger 2.3 引入lo ...

  10. 基于Vite + Vue3 + Typescript 实现在线聊天项目

    前言 本项目是本人的毕业设计,在校的时候看着同学都都开始一步一步的开始准备毕设了,刚好那段时间正在了解websocket,于是有了个想法,毕设能不能做一个在线聊天的系统. 前端技术用到了 Vue3 + ...

最新文章

  1. aggr代码 cellranger_单细胞转录组测序数据分析流程-数据预处理
  2. jflash合并stm32f103之bin文件及hex文件
  3. 一款让你“乐词不疲”的背单词神器
  4. 基于hi-nginx的web开发(python篇)——utf-8编码
  5. 高效的企业测试–测试框架(5/6)
  6. D3 datumdata
  7. SpringCloud Config详解
  8. 阿里云语音识别模型端核心技术选讲
  9. primefaces教程_Primefaces Spring和Hibernate集成示例教程
  10. linux源码安装php,nginx配置php
  11. 群体智能算法之蝙蝠算法
  12. 盘点40种常用的芯片封装技术
  13. iText5实现Java生成PDF文件完整版
  14. 键盘表和ASCII码表
  15. CacheCloud安装配置
  16. 阿里云跨云迁移工具案例实践:华为云迁移到阿里云
  17. 美国国家机器人计划2.0部分项目简介
  18. 计算性和复杂度理论2
  19. 运维简历怎么写项目描述_职场小白怎么写简历?一份好简历=成功一半
  20. 数据库系统概论复习提纲

热门文章

  1. 3.6 Spark安装与体验
  2. Spark:Spark 编程模型及快速入门
  3. 【论文阅读】Efficient Net
  4. 伪标记是一种简单的半监督学习方法
  5. 新型消防机器人作文_说一说消防机器人
  6. python与r语言处理excel数据_【R语言】批量读取Excel数据并合并(升级版)
  7. tensorflow如何微调时如何只训练后两层_XLNet只存在于论文?都替你封装好了还不来用!...
  8. 关于sophus模板类需要注意的情况(error: missing template arguments before ‘SO3_R’)
  9. Linux字体最好看的发行版,如何给任意一款 Linux 发行版添加漂亮的字体
  10. 《永不放弃-马云给创业者的24堂课》— 综合素质提升书籍