有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java BufferReader显然没有从socket接收数据。简单聊天服务

你能看一下我的代码并告诉我这里有什么问题吗? 我学习java网络编程和网络一般都是为了好玩,我试着遵循这个https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html,但不是创建协议,而是尝试在服务器和客户端之间创建简单的消息交换

标准输出中没有显示任何内容,当我调试时,BufferReader buffer是空的,似乎不接收数据。我还没有和Wireshark核实,但我怀疑原因更为琐碎,是我缺乏经验的结果

这是客户机代码(它首先用一个简单的“Hello There”向服务器发送消息)

 try(BufferedReader fromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintWriter toServer = new PrintWriter(socket.getOutputStream());
        BufferedReader consoleInput = new BufferedReader(new InputStreamReader(System.in));
    ){

        toServer.println("Hello there!");

        while(!goodbye){
            if(fromServer.ready())                        //if stream is empty this prevents a freeze
                msgFromServer = fromServer.readLine();
            if(msgFromServer != null) {
                System.out.println("Server: " + msgFromServer);
                if(msgFromServer.equals("Bye"))
                    goodbye = true;
            }

            msgToServer = consoleInput.readLine();
            if(msgToServer != null) {
                toServer.println(msgToServer);
                if(msgToServer.equals("Bye"))
                    goodbye = true;
            }

        }
        socket.close();

    } catch (IOException e) {
        e.printStackTrace();
    }

现在服务器端

      try(Socket clientSocket = socket.accept();
            BufferedReader fromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter toClient = new PrintWriter(clientSocket.getOutputStream());
            BufferedReader consoleInput = new BufferedReader(new InputStreamReader(System.in));
        ){

            while(!goodbye){
                if(fromClient.ready())
                    msgFromClient = fromClient.readLine();
                if(msgFromClient != null) {
                    System.out.println("Client: " + msgFromClient);
                    if(msgFromClient.equals("Bye"))
                        goodbye = true;
                }

                msgToClient = consoleInput.readLine();
                if(msgToClient != null) {
                    toClient.println(msgToClient);
                    if(msgToClient.equals("Bye"))
                        goodbye = true;
                }

            }

            socket.close();

        } catch(IOException ex){
            System.out.println(ex);
        }

我已经被所有的循环弄糊涂了,不知道它们是否有可能以某种方式不同步,而我的策略通常是错误的?也许我应该设置一些标志为“等待服务器回复”,我真的很困惑

编辑:在注释后if(BufferedReader.ready()) 它工作的每个类中的方法。我仍然不确定为什么,所以我现在还不会关闭它,但在我找到答案后,我会在单独的答案中解释 到目前为止,我的“固定”代码如下所示:

 try(Socket clientSocket = socket.accept();
            BufferedReader fromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            BufferedWriter toClient = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
            BufferedReader consoleInput = new BufferedReader(new InputStreamReader(System.in));
        ){

            while(!goodbye){
                //if(fromClient.ready())
                    msgFromClient = fromClient.readLine();
                if(msgFromClient != null) {
                    System.out.println("Client: " + msgFromClient);
                    if(msgFromClient.equals("Bye"))
                        goodbye = true;
                }

                msgToClient = consoleInput.readLine();
                if(msgToClient != null) {
                   toClient.write(msgToClient);
                   toClient.newLine();
                   toClient.flush();                        
                    if(msgToClient.equals("Bye"))
                        goodbye = true;
                }

            }

            socket.close();

        } catch(IOException ex){
            System.out.println(ex);
        }

我忘了,但我还向客户机socket添加了Socket.TcpSetNoDelay(true)


共 (2) 个答案

  1. # 1 楼答案

    在注释掉每个类中的if(BufferedReader.ready())方法之后,它就工作了。 看起来我对这个方法的作用有错误的想法。 我加了一句。ready()方法,因为服务器在上冻结。readLine(),因为我在从客户端写入流之后和调试期间没有使用flush()方法,这表明这里可能有问题

    正如@VGR所指出的那样 所有的ready()方法所做的就是判断是否存在等待流数据到达的延迟。第一条消息必须有一个延迟,所以它直到下一个缓冲区读取时才显示,当时它已经在缓冲区中了

    我还向客户机套接字添加了Socket.TcpSetNoDelay(true)

    代码现在看起来像这样 服务器:

    try(Socket clientSocket = socket.accept();
            BufferedReader fromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            BufferedWriter toClient = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
            BufferedReader consoleInput = new BufferedReader(new InputStreamReader(System.in));
        ){
    
            while(!goodbye){
                //if(fromClient.ready())
                    msgFromClient = fromClient.readLine();
                if(msgFromClient != null) {
                    System.out.println("Client: " + msgFromClient);
                    if(msgFromClient.equals("Bye"))
                        goodbye = true;
                }
    
                msgToClient = consoleInput.readLine();
                if(msgToClient != null) {
                   toClient.write(msgToClient);
                   toClient.newLine();
                   toClient.flush();                        
                    if(msgToClient.equals("Bye"))
                        goodbye = true;
                }
    
            }
    
            socket.close();
    
        } catch(IOException ex){
            System.out.println(ex);
        }
    

    客户端

    Clientv2(){
        socket = new Socket();
        try {
            socket.setTcpNoDelay(true); //this is new too
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
    
    public void connect() {
        try {
            socket.connect(new InetSocketAddress(serverHostname, serverPort));
        }
        catch (IOException ex){
            System.out.println(ex);
        }
    
        try(BufferedReader fromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedWriter toServer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            BufferedReader consoleInput = new BufferedReader(new InputStreamReader(System.in));
        ){
    
            toServer.write("Hello there!");
            toServer.newLine();
            toServer.flush();
    
            while(!goodbye){
                //if(fromServer.ready())                        //culprit
                    msgFromServer = fromServer.readLine();
                if(msgFromServer != null) {
                    System.out.println("Server: " + msgFromServer);
                    if(msgFromServer.equals("Bye"))
                        goodbye = true;
                }
    
                msgToServer = consoleInput.readLine();
                if(msgToServer != null) {
                    toServer.write(msgToServer);
                    toServer.newLine();
                    toServer.flush();
                    if(msgToServer.equals("Bye"))
                        goodbye = true;
                }
    
            }
            socket.close();
    
  2. # 2 楼答案

    我认为你应该尝试使用熟悉的课程来阅读和写作。例如,如果您使用BufferedReader进行读取,那么您应该使用BufferedWriter进行写入