阅读

时间:2018-03-22 10:58:11

标签: java sockets

基本上,我想要实现的是在客户端套接字和服务器套接字之间完成ping-pang通信。

场景应该是这样的:

  1. 客户端建立与服务器的连接。
  2. 客户端向服务器发送“Hello”(通过OutputStream),然后开始从服务器读取(通过InputStream)
  3. 服务器读取“Hello”消息并打印到控制台,然后向客户端发送“Hello”(通过OutputSteam)。
  4. 客户端从服务器打印响应消息并退出。
  5. 服务器套接字

    try (ServerSocket serverSocket = new ServerSocket(8080)) {
                while (true) {
                    // Blocking here
                    Socket socket = serverSocket.accept();
                    InputStream inStream = socket.getInputStream();
                    OutputStream outStream = socket.getOutputStream();
    
                    String reqMessage = new String(inStream.readAllBytes(), StandardCharsets.UTF_8);
                    System.out.println(reqMessage);
    
                    String resMessage = "Hello";
                    outStream.write(resMessage.getBytes(StandardCharsets.UTF_8));
                    outStream.flush();
                    System.out.println(String.format("Message '%s' has been sent to client", resMessage));
    
                    outStream.close();
                    socket.close();
                }
            }
    

    客户端套接字:

    Socket socket = new Socket("localhost", 8080);
    
            OutputStream outStream = socket.getOutputStream();
            outStream.write("Hello Server".getBytes(StandardCharsets.UTF_8));
            outStream.flush();
    
            InputStream inStream = socket.getInputStream();
            System.out.println("Received from server");
            System.out.println(new String(inStream.readAllBytes(), StandardCharsets.UTF_8));
    
            outStream.close();
            socket.close();
    

    我的问题:

    一旦建立连接,双方都被阻止,没有人正在打印正确的消息,就像他们正在等待彼此一样。一旦我关闭客户端,服务器就会输出所有正确的信息。但是,如果我从客户端删除了“从服务器读取”部分,即InputStream部分,那么双方都正常工作。我只是感到困惑,为什么它会像这样?如果我想让它工作,我应该修改什么?

    感谢。

1 个答案:

答案 0 :(得分:0)

您的问题出在readAllBytes()。它并不意味着它读取所有可用的字节,它会读取所有字节,直到流关闭

String reqMessage = new String(inStream.readAllBytes(), StandardCharsets.UTF_8);

将阻止,直到您关闭客户端,因为服务器仍在等待"所有"字节。同时客户端正在等待服务器发送一些东西,当然它还在等待来自客户端的更多数据。

您无论如何都不应该使用字节,因为您正在编写短信。将BufferedReaderInputStreamReader一起使用,例如PrintWriterOutputStreamWriter一起使用来撰写文字。不要忘记readLine()需要发件人的换行符,并在InputStreamReaderOutputStreamWriter中指定字符编码。