即使在套接字读取器到达 EOF 之后,如何发送套接字写入器响应?

问题描述 投票:0回答:1

代码持续侦听 POST 请求,并在完全读取套接字输入数据后发送响应。

但事实证明,Java 运行时会自动关闭连接到套接字和标准输入流的读取器和写入器,并且每当在读取数据时达到 EOF(如 Oracle 文档中所述)时,它就会关闭与服务器的套接字连接这里.

我正在使用这种方式读取数据(reader是'客户端套接字的输入流'):

while ((line = reader.readLine()) != null) {
    requestData+=line+"\n";
}

这会导致读取器到达 EOF,并导致所有套接字读取器和写入器自动关闭,这是我不希望发生的情况。在发送响应之前,我需要知道 requestData。自动关闭连接的套接字阻止我这样做。

因此,每次我尝试从“http://192.168.129.185:9999/”打开它时,页面都会不断加载,而不是以纯文本显示输出。

我需要一个解决方法。

当前代码

完整代码是这样的:

import java.io.*;
import java.net.*;

class Server{
    static int count= 0;
    public static void main()throws Exception{
        String address = "192.168.129.185";
        int port = 9999;
        ServerSocket serverSocket = new ServerSocket(port, 1, InetAddress.getByName(address));

        while (true) {
            Socket clientSocket = serverSocket.accept();
            // Handle client connection in a separate thread (recommended)
            new Thread(() -> handleClient(clientSocket)).start();
        }

    }

    public static void handleClient(Socket clientSocket) {
        try (PrintWriter writer = new PrintWriter(clientSocket.getOutputStream() , true);
        BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {

            
            //READ SOCKET DATA UNTIL EOF IS REACHED
            String requestData = "";
            int lineCount= 0;
            String line;
            while ((line = reader.readLine()) != null) {
                requestData+=line+"\n";
                lineCount++;
            }
            
            //when reader.readLine() reaches EOF, codes below this DO get executed, but NO response provided

            String responseHeader = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";

            // Write the response header and message
            writer.print(responseHeader);
            
            writer.print("{\"reply\":\""+count+"\"}");//ACTUAL RESPONSE DATA TO BE SENT

            writer.flush();

            
            count++;

                
        } catch (IOException e) {
            System.out.println("ERROR");
            e.printStackTrace();

        } finally {
            // Close the client socket even on exceptions
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            finally{
            }
        }
    }

}

[这是导致问题的当前代码]

上面代码中涉及到的函数是这样的:

    public static void handleClient(Socket clientSocket) {
        try (PrintWriter writer = new PrintWriter(clientSocket.getOutputStream() , true);
        BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {

            
            //READ SOCKET DATA UNTIL EOF IS REACHED
            String requestData = "";
            int lineCount= 0;
            String line;
            while ((line = reader.readLine()) != null) {
                requestData+=line+"\n";
                lineCount++;
            }
            
            //when reader.readLine() reaches EOF, codes below this DO get executed, but NO response provided

            String responseHeader = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";

            // Write the response header and message
            writer.print(responseHeader);
            
            writer.print("{\"reply\":\""+count+"\"}");//ACTUAL RESPONSE DATA TO BE SENT

            writer.flush();

            
            count++;

                
        } catch (IOException e) {
            System.out.println("ERROR");
            e.printStackTrace();

        } finally {
            // Close the client socket even on exceptions
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            finally{
            }
        }
    }

尝试

//READ SOCKET DATA UNTIL EOF IS REACHED
String requestData = "";
int lineCount= 0;
String line;
while ((line = reader.readLine()) != null & (lineCount <= 1)) {
      requestData+=line+"\n";
      lineCount++;
}

此片段在 while 循环中包含

(lineCount <= 1)
,导致它仅检查第一行并避免到达 EOF。这段代码使代码完美运行。发送请求后,它成功返回响应,如
writer.print("{\"reply\":\""+count+"\"}");
中所示。 现在,这并不是很有用,因为我需要读取完整的套接字输入,而不仅仅是第一行。

此片段只是代码本身正在运行的演示。只有达到 EOF 时自动关闭套接字才是问题。

java sockets networking echo-server
1个回答
0
投票

您阅读直到 EOF 的方法从一开始就是错误的。相反,您需要读取请求标头,解析它以提取预期正文的长度(即内容长度标头给出的固定长度或传输编码分块的几个块),然后根据给定的长度读取正文。客户端在请求后不会关闭连接,而是等待服务器响应(或在未收到响应时超时后关闭)。

© www.soinside.com 2019 - 2024. All rights reserved.