启斌呢 2023-12-05 21:17 采纳率: 80%
浏览 38

java.io.StreamCorruptedException: invalid stream header: 0005001D

Exception in thread "Thread-2" Exception in thread "Thread-1" java.lang.RuntimeException: java.io.StreamCorruptedException: invalid stream header: 0005001D
我试了好久就是找不到原因啊!
一个简单的网络通讯demo
寻找在线用户功能是可以反复运行的,但是一旦用了其他功能1次,就什么功能都用不了了
客户端1运行结果

img

客户端2运行结果

img

可以看到一旦发送了私信,第一次还是可以的,但之后就算运行返回在线用户功能也没用了
客户端界面代码

   public void showSecondMenu() {
        System.out.println("!!!!!!!!!恭喜登录成功!!!!!!!!!");
        String[] secondMenuKeys = {"1", "2", "3", "4", "9"};
        //进入到二级菜单
        while (secondMenuLoop) {
            System.out.println("\n=========网络通信系统二级菜单(用户" + account + ")=======");
            System.out.println("\t\t 1 显示在线用户列表");
            System.out.println("\t\t 2 私聊消息");
            System.out.println("\t\t 3 群发消息");
            System.out.println("\t\t 4 发送文件");
            System.out.println("\t\t 9 退出系统");
            System.out.print("请输入你的选择: ");
            key = ReadInputUtils.readMenuSelection(secondMenuKeys, 1);
            switch (key) {
                case "1":
                    System.out.println("---启动获取在线用户列表功能");
                    userClientService.getOnlineFriend(account,password);
                    System.out.println("---获取在线用户列表功能运行完毕");
                    break;
                case "2":
                    System.out.print("请输入想要发送消息朋友的账号:");
                    getterAccount = ReadInputUtils.readString(10);
                    System.out.print("请输入文本信息:");
                    txtMessage = ReadInputUtils.readString(100);
                    System.out.println("---启动发送私信功能");
                    messageClientService.sendFriendMessage(account,getterAccount,txtMessage);
                    System.out.println("---发送私信功能运行完毕");
                    break;
                case "3":
                    System.out.print("请输入群发的文本信息:");
                    txtMessage = ReadInputUtils.readString(100);
                    messageClientService.sendPeopleMessage(account,txtMessage);
                    break;
                case "4":
                    System.out.print("请输入想要发送消息朋友的账号:");
                    getterAccount = ReadInputUtils.readString(10);
                    System.out.print("请输入文件源路径:");
                    String fileSourcePath = ReadInputUtils.readString(50);
                    System.out.print("请输入文件存储路径:");
                    String fileDownloadPath = ReadInputUtils.readString(50);
                    fileClientService.sendFriendFile(account,getterAccount,fileSourcePath,fileDownloadPath);
                    break;
                case "9":
                    userClientService.Logout(account);
                    break;
            }
        }
    }

客户端用户服务

  /**
     * 功能:返回在线用户
     * @param account 客户端账号
     * @param password 客户端密码
     */
    public void getOnlineFriend(String account,String password){
        /**
         * 创建消息
         */
        messageToServer.setSendTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss")));
        messageToServer.setMesType(MessageType.Message_GET_ONLINE_FRIEND);
        messageToServer.setSender(account);
        messageToServer.setGetter("GETTER_SERVER");
        messageToServer.setTestContent("客户端请求返回在线用户");
        messageToServer.setUser(new User(account,password));
        System.out.println("---请求返回在线用户列表消息编辑完成");
        /**
         * 发送消息
         */
        try {
            //根据用户账号获取线程
            ClientConnectServerThread clientThread = ManageClientConnectServerThread.getClientSocket(account);
            //根据线程获取socket
            Socket clientSocket = clientThread.getClientSocket();
            ObjectOutputStream objectOutputStream =
                    new ObjectOutputStream(clientSocket.getOutputStream());
            //发送消息
            objectOutputStream.writeObject(messageToServer);
            System.out.println("---请求返回在线用户列表消息发送完成");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

**服务端接收消息
**

public class ServerConnectClientThread extends Thread {
    /**
     * 属性初始化
     */
    private Socket socketServer;
    private Message messageFromClient = new Message();//接收客户端消息
    private Message messageToClient = new Message();//发送服务端消息

    private UserServerService userServerService = new UserServerService();

    @Override
    public void run() {
        while (true) {
            try {
                /**
                 * 接收客户端消息
                 */
                ObjectInputStream objectInputStream =
                        new ObjectInputStream(socketServer.getInputStream());
                messageFromClient = (Message) objectInputStream.readObject();
                System.out.println("---来自客户端的消息接收完毕");
//                messageToClient = CloneUtils.deepClone(messageFromClient);
                /**
                 * 根据不同类型消息来处理数据并返回消息
                 */
                if (messageFromClient.getMesType().equals(MessageType.Message_GET_ONLINE_FRIEND)) {//客户端要求返回在线用户消息
                    System.out.println("---消息检验完毕:客户端请求返回在线用户列表");
                    //创建在线用户集合
                    List<User> userOnlineList = userServerService.getOnlineFriend(messageFromClient.getSender());
                    System.out.println("---创建在线用户集合");
                    //创建消息
                    messageToClient.setSendTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss")));
                    messageToClient.setSender("SENDER_SERVER");
                    messageToClient.setMesType(MessageType.Message_RET_ONLINE_FRIEND);
                    messageToClient.setTestContent("服务端响应客户端的返回在线用户");
                    messageToClient.setList(userOnlineList);
                    System.out.println("---返回客户端在线用户列表消息编辑完成");
                    //发送消息
                    ObjectOutputStream objectOutputStream =
                            new ObjectOutputStream(socketServer.getOutputStream());
                    objectOutputStream.writeObject(messageToClient);
                    System.out.println("---返回客户端在线用户列表消息发送完毕");
                }else if (messageFromClient.getMesType().equals(MessageType.Message_COMMON_MES)){//客户端发送私信
                    System.out.println("---消息检验完毕:客户端请求发送私信");
                    //创建消息
                     messageToClient.setSendTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss")));
                     messageToClient.setSender(messageFromClient.getSender());
                     messageToClient.setGetter(messageFromClient.getGetter());
                     messageToClient.setMesType(MessageType.Message_COMMON_MES);
                     messageToClient.setTestContent(messageFromClient.getTestContent());
                    //获取接受用户socket
                    socketServer = ManageServerConnectClientThread.getServerConnectClientThread(messageFromClient.getGetter()).socketServer;
                    //发送消息
                    ObjectOutputStream objectOutputStream =
                            new ObjectOutputStream(socketServer.getOutputStream());
                    objectOutputStream.writeObject(messageToClient);
                    System.out.println("---返回客户端私信消息完毕");
                } else if (messageFromClient.getMesType().equals(MessageType.Message_TO_ALL_MES)) {//客户端群发消息
                    //创建消息
                    messageToClient.setSendTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss")));
                    messageToClient.setSender(messageFromClient.getSender());
                    messageToClient.setMesType(MessageType.Message_TO_ALL_MES);
                    messageToClient.setTestContent(messageFromClient.getTestContent());
                   //群发消息
                    for (String clientAccount:ManageServerConnectClientThread.getHashMap().keySet()){//迭代获取账号
                        ServerConnectClientThread serverConnectClientThread
                                = ManageServerConnectClientThread.getServerConnectClientThread(clientAccount);//根据账号获取线程
                        socketServer = serverConnectClientThread.getSocketServer();//获取socket
                        messageToClient.setGetter(clientAccount);//确定接收方
                        //发送消息
                        ObjectOutputStream objectOutputStream =
                                new ObjectOutputStream(socketServer.getOutputStream());
                        objectOutputStream.writeObject(messageToClient);
                    }
                } else if (messageFromClient.getMesType().equals(MessageType.Message_FILE_MES)) {//客户端发送文件
                    //创建消息
                    messageToClient.setSendTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss")));
                    messageToClient.setSender(messageFromClient.getSender());
                    messageToClient.setMesType(MessageType.Message_FILE_MES);
                    messageToClient.setFileBytes(messageFromClient.getFileBytes());
                    messageToClient.setDesc(messageFromClient.getDesc());
                    messageToClient.setSrc(messageFromClient.getSrc());
                    //获取接受用户socket
                    socketServer = ManageServerConnectClientThread.getServerConnectClientThread(messageFromClient.getGetter()).socketServer;
                    //发送消息
                    ObjectOutputStream objectOutputStream =
                            new ObjectOutputStream(socketServer.getOutputStream());
                    objectOutputStream.writeObject(messageToClient);
                } else if (messageFromClient.getMesType().equals(MessageType.Message_CLIENT_EXIT)) {//客户端要求退出
                    //删除集合里的线程
                    ManageServerConnectClientThread.removeServerConnectClientThread(messageFromClient.getSender());
                    //关闭socket
                    socketServer.close();
                    //退出当前线程
                    break;
                } else {
                    System.out.println("其他类型的message , 暂时不处理");
                }
            } catch (IOException | ClassNotFoundException e) {
                throw new RuntimeException(e);
            }

        }

    }

    public ServerConnectClientThread(Socket socketServer) {
        this.socketServer = socketServer;
    }

    public Socket getSocketServer() {
        return socketServer;
    }

    public void setSocketServer(Socket socketServer) {
        this.socketServer = socketServer;
    }
}


客户端接收消息

public class ClientConnectServerThread extends Thread{
    /**
     * 各类属性初始化
     */
    private Socket clientSocket;
    private Message messageFromServer;

    @Override
    public void run() {
        /**
         * 因为Thread需要在后台和服务器通信,因此我们while循环
         */
        System.out.println("客户端等待服务端发送消息中.......");
        while(true){
            try {
                ObjectInputStream objectInputStream =
                        new ObjectInputStream(clientSocket.getInputStream());
                messageFromServer =(Message) objectInputStream.readObject();
                System.out.println("---来自服务端消息接收完毕");
                /**
                 * 根据不同消息类型处理
                 */
                if (messageFromServer.getMesType().equals(MessageType.Message_RET_ONLINE_FRIEND)){//服务端返回客户端的在线用户请求
                    System.out.println("---来自服务端消息验证为返回在线用户列表");
                    //打印集合
                    if (!messageFromServer.getList().isEmpty()) {
                        System.out.println();
                        System.out.println("!!!!!!在线用户如下!!!!!");
                        for (User user : messageFromServer.getList()) {
                            System.out.println(user.getUser_Accountstr() + "\t\t\t\t" + user.getUser_Namestr());
                        }
                    }else{
                        System.out.println();
                        System.out.println("当前无用户在线");
                    }
                    System.out.println("---在线用户列表打印完毕");

                } else if (messageFromServer.getMesType().equals(MessageType.Message_COMMON_MES)) {//服务端返回客户端私聊的私信
                    System.out.println("---来自服务端消息验证为发送私信");
                    System.out.println();
                    System.out.println("==============聊天界面==============");
                    System.out.println(messageFromServer.getSender()+"对"+messageFromServer.getGetter()+"说:"+messageFromServer.getTestContent());
                    System.out.println("---发送私信打印完毕");
                } else if (messageFromServer.getMesType().equals(MessageType.Message_TO_ALL_MES)) {//服务端返回客户端发送的群发消息
                    System.out.println();
                    System.out.println("==============聊天界面==============");
                    System.out.println(messageFromServer.getSender()+"对大家说:"+messageFromServer.getTestContent());

                }else if (messageFromServer.getMesType().equals(MessageType.Message_FILE_MES)){
                    System.out.println("==============传输文件界面==============");
                    System.out.println(messageFromServer.getSender()+"对"+messageFromServer.getGetter()+"发送文件中.....");
                    FileOutputStream fileOutputStream = new FileOutputStream(messageFromServer.getDesc());
                    fileOutputStream.write(messageFromServer.getFileBytes(),0,messageFromServer.getFileLen());
                    fileOutputStream.close();
                    System.out.println("传输完成");
                }

            } catch (IOException | ClassNotFoundException e) {
                throw new RuntimeException(e);
            }

        }

    }

    public ClientConnectServerThread(Socket clientSocket) {
        this.clientSocket = clientSocket;
    }

    public Socket getClientSocket() {
        return clientSocket;
    }

    public void setClientSocket(Socket clientSocket) {
        this.clientSocket = clientSocket;
    }
}


  • 写回答

2条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-12-06 08:58
    关注

    【以下回答由 GPT 生成】

    非常抱歉,由于我无法看到实际的服务器端代码,所以我无法直接提供准确的解决方案。然而,我可以给出一些常见的排查步骤,希望能帮助你找到问题所在。

    1. 确保服务器端代码与客户端代码使用的通信协议和版本相同。检查服务器端和客户端的通信协议是否一致,以确保数据能够正确传输。

    2. 检查服务器端代码中的数据读写逻辑。确保在服务器端读取和写入数据时没有出现任何异常或错误。可以使用try-catch来捕获可能的异常,并在遇到异常时进行适当的处理。

    3. 检查服务器端代码中的数据处理逻辑。确保服务器端能够正确地解析和处理客户端发送的数据。可以逐步检查服务器端代码中的每个处理步骤,确认每一步都正确执行,没有出现任何异常或错误。

    4. 检查服务器端代码中与网络通信相关的配置。确保服务器端的网络配置正确,并且服务器端可以正常监听和接受客户端的连接。

    5. 检查服务器端代码中的并发处理能力。如果服务器端需要同时处理多个客户端的请求,确保服务器端有足够的并发处理能力,并使用适当的方式来处理并发请求,以避免数据错乱或冲突。

    以上是一些常见的排查步骤,希望能帮助你找到问题所在。如果以上步骤不能解决你的问题,建议你提供更多关于服务器端代码的信息,并尽量给出具体的错误提示或异常堆栈信息,以便更好地帮助你解决问题。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 12月5日