ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2021-09-20 15:36:14  阅读:156  来源: 互联网

标签:java socket 服务器端 线程 EOFException Message 多线程 message 客户端


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,socket,服务器端,线程,EOFException,Message,多线程,message,客户端
来源: https://www.cnblogs.com/wenhaozou/p/15314357.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有