Java网络多线程开发:java.io.EOFException

在实现韩顺平Java的多用户即使通信系统实战项目中:

对于客户端线程的停止,老韩是向服务器端发送一个消息对象,提示服务器端进行资源释放(包含线程集合资源以及socket连接断开)。对于客户端部分,使用如下代码:

// 编写一个方法,退出客户端,并给服务器端发送一个退出系统的消息对象
public void logout() {
Message message = new Message();
message.setMesType(MessageType.MESSAGE_CLEAR_EXIT);
message.setSender(u.getUserId());
// 发送message对象
try {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(message);
System.out.println(TimeGet.getLocalTime() + " 用户:" + u.getUserId() + " 退出系统 ");
System.exit(0); // 结束虚拟机,客户端
} catch (IOException e) {
e.printStackTrace();
}
}

然而,当登录用户成功后,再进行退出系统操作,会发生java.io.EOFException:

定位到提示错误的代码行,发现这个错误其实是在说明客户端监听服务器端Message的线程依然在进行中:

public class ClientConnectServerThread extends Thread{
private Socket socket;//该线程需要持有Socket public ClientConnectServerThread(Socket socket) {
this.socket = socket;
} @Override
public void run() {
while (true) {
try {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); //报错的代码行
Message ms = (Message) ois.readObject();

解决方法:

服务器端在接收到客户端发来的退出系统消息后,向客户端发出回应,客户端监听到服务器端发来的回应后,立马取消监听。

服务器端:收到客户端退出系统消息后,向客户端回应

            .....................
} else if (message.getMesType().equals(MessageType.MESSAGE_CLEAR_EXIT)) { // 客户端要退出系统
// 解决方案==============
Message message2 = new Message();
//设置当前message1是一条返回用户列表信息的信息对象
message2.setMesType(MessageType.MESSAGE_CLEAR_EXIT);
message2.setGetter(message.getSender());
// 将message对象返回给客户端
ObjectOutputStream oos1 = new ObjectOutputStream(socket.getOutputStream());
oos1.writeObject(message2);
// ========================= ManageClientThreads.removeClientThread(userId); // 释放服务器线程库资源
socket.close(); // 关闭连接
break; // 退出线程
} else {
..........

客户端:很简单,break,结束监听进程

                else if (ms.getMesType().equals(MessageType.MESSAGE_CLEAR_EXIT)) {
// ManageClientConnectServerThread.removeThreadSource(ms.getGetter());
// socket.close();
break;
}

客户端完整的监听服务器端的代码:

public class ClientConnectServerThread extends Thread{
private Socket socket;//该线程需要持有Socket public ClientConnectServerThread(Socket socket) { //构造器
this.socket = socket;
} @Override
public void run() {
while (true) {// 线程需要不停地监听服务器是否发送了Message
try {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Message ms = (Message) ois.readObject();// 如果服务器没有发送Message对象,线程会阻塞在这里 // 根据服务器返回message对象的类型,进行相应的处理
if (ms.getMesType().equals(MessageType.MESSAGE_RET_ONLINE_FRIEND)) {
String[] mesArray = ms.getComment().split(" "); // 服务器端每一条数据后,都用空格符进行区分
for (String s : mesArray) {
System.out.println(s);
}
}
else if (ms.getMesType().equals(MessageType.MESSAGE_CLEAR_EXIT)) {
// ManageClientConnectServerThread.removeThreadSource(ms.getGetter());
// socket.close();
break;
}
else {
System.out.println("其他消息暂时不处理!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
} public Socket getSocket(){
return socket;
}
}

Java网络多线程开发:java.io.EOFException的更多相关文章

  1. Java网络多线程编程:对象流错误导致Connection reset

    Java网络多线程编程--对象流错误导致Connection reset 在老韩的网络多线程编程实战项目中,发生了如下报错: 服务器端和客户端均发生了报错,在确定相应对象流代码完全没有问题之后,回归定 ...

  2. Java之多线程开发时多条件Condition接口的使用

    转:http://blog.csdn.net/a352193394/article/details/39454157 我们在多线程开发中,可能会出现这种情况.就是一个线程需要另外一个线程满足某某条件才 ...

  3. Java:多线程,java.util.concurrent.atomic包之AtomicInteger/AtomicLong用法

    1. 背景 java.util.concurrent.atomic这个包是非常实用,解决了我们以前自己写一个同步方法来实现类似于自增长字段的问题. 在Java语言中,增量操作符(++)不是原子的,也就 ...

  4. JAVA与多线程开发(线程基础、继承Thread类来定义自己的线程、实现Runnable接口来解决单继承局限性、控制多线程程并发)

    实现线程并发有两种方式:1)继承Thread类:2)实现Runnable接口. 线程基础 1)程序.进程.线程:并行.并发. 2)线程生命周期:创建状态(new一个线程对象).就绪状态(调用该对象的s ...

  5. Java 网络处理(net io URL 等)

    1. URL 类 URL 类的两个重要方法: openStream():打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream. URL url = new URL(" ...

  6. Java网络编程的Java流介绍

    前言 网络程序所做的很大一部分工作都是简单的输入输出:将数据字节从一个系统移动到另一个系统.Java的I/O建立于流(stream)之上.输入流读取数据,输出流写入数据.过滤器流(filter)流可以 ...

  7. JAVA EE企业级开发四步走完全攻略 [转]

    http://bbs.51cto.com/thread-550558-1.html 本文是J2EE企业级开发四步走完全攻略索引,因内容比较广泛,涉及整个JAVA EE开发相关知识,这是一个长期的计划, ...

  8. Java网络编程和NIO详解开篇:Java网络编程基础

    Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...

  9. Java网络编程和NIO详解9:基于NIO的网络编程框架Netty

    Java网络编程和NIO详解9:基于NIO的网络编程框架Netty 转自https://sylvanassun.github.io/2017/11/30/2017-11-30-netty_introd ...

随机推荐

  1. [nowcoder5669A]Ancient Distance

    对于一个$k$,可以二分枚举答案并判断,判断过程可以贪心找最深的点(线段树区间max)+倍增+线段树区间覆盖(清0)来实现,时间复杂度$o(klog_{2}n)$ 考虑反过来,暴力枚举答案$x$并求出 ...

  2. html+css第十篇-命名

    命名:根据每块元素的主题 或者功能.在页面上的位置 php 每个单词中间以"_"隔开 #main_left_box{} 驼峰命名 从第二个单词开始每个单词的首字母大写 #mainL ...

  3. 咸阳市大数据管理局使用Rainbond作为智慧城市底座的实践

    使用 Rainbond 作为智慧城市底座之后,给我们带来了成倍的运维效率提升. -- 咸阳市大数据管理局 熊礼智 咸阳市大数据管理局负责全市信息共享工作的组织领导,协调解决与政府信息共享有关的重大问题 ...

  4. 9.3 k8s结合ELK实现日志收集

    数据流: logfile -> filebeat > kafka(依赖zookeeper)-> logstash -> elasticsearch -> kibana 1 ...

  5. Java培训班4个月有用吗?

    很多想学Java都会经历这样一个选择,是自学还是报班?自学的话需要一步步摸索,从无到有硬啃下来,时间没保证:可如果报班的话,目前市面上五花八门的培训机构又是鱼龙混杂,并且现在越来越多的培训机构宣称&q ...

  6. linux中conda升级R到4.0?

    目录 前言 问题 曲线救国 前言 虽然我的win版本R已经用4了,但之前在Linux环境一直没用R4.0,因为Linux涉及的东西太多,担心不稳定,牵一发而动全身. 但现在有好些R包必须要用更新到R4 ...

  7. R包xlsx安装与使用

     1. Rstudio安装xlsx报错 xlsx包加载依赖Java环境,我之前就安装过Java,但安装xlsx成功后,加载xlsx时一直报错: Error : loadNamespace()里算'rJ ...

  8. Python3编译安装ssl模块问题

    本文以Centos系统为例 1.确保linux系统中安装了ssl-devel包 2.编译安装ssl模块到Python3中 1.查看linux系统中是否安装了ssl-devel包 # 查看命令 rpm ...

  9. 65-Binary Tree Zigzag Level Order Traversal

    Binary Tree Zigzag Level Order Traversal My Submissions QuestionEditorial Solution Total Accepted: 6 ...

  10. PHP-FPM运行状态的实时查看及监控详解

    https://www.jb51.net/article/97640.htm https://blog.csdn.net/Dr_cokiy/article/details/105580758