从socket读取如何检测客户端何时完成发送请求?

时间:2012-11-12 23:54:54

标签: java sockets httprequest httpserver

我现在正在写一个http服务器,我在从套接字读取时遇到问题。 我的问题是来自客户端的inputStream永远不会结束,并且一直在阅读,直到客户端关闭。 我知道客户端在发送http请求后不会立即关闭与服务器的连接。 当客户端发送了所有请求数据(即标题+正文)时,如何退出while loop

while (in.hasNextLine()) {
    String line = in.nextLine();

    if (line.equals("")){ // last line of request header is blank
        break; // quit while loop when last line of header is reached
    } else {
        request = request + line + "\n";
    }
}

在阅读了你们的评论和回答之后,这就是我想出来的,

     is = incoming.getInputStream();
            os = incoming.getOutputStream();
            in = new Scanner(is);
            out = new DataOutputStream(os);

            RequestHandler rh = new RequestHandler();
            int length = 0;
            while (in.hasNextLine()) {
                String line = in.nextLine();
                if (line.equals("")) { // last line of request message
                                        // header is a
                                        // blank line
                    break; // quit while loop when last line of header is
                            // reached
                }

                if (line.startsWith("Content-Length: ")) { // get the
                                                            // content-length
                    int index = line.indexOf(':') + 1;
                    String len = line.substring(index).trim();
                    length = Integer.parseInt(len);
                }

                request = request + line + "\n";
            }

             byte[] body = new byte[length];
             int i = 0;
             while (i < length) {
             byte b = in.nextByte();
             body[i] = b;
             i++;
             }

但是,我仍然不知道按字节读取。我可以编写我的代码来读取-1,但是当没有EOF且客户端没有关闭连接时仍然卡住。

3 个答案:

答案 0 :(得分:5)

根据您正在处理的请求,有三种方法可以检测流的结束:

  1. 如果是GETHEAD请求,您只需要读取HTTP标头,如果存在请求正文通常会被忽略,那么当您遇到\r\n\r\n时,您就会触及请求的结尾(实际上是请求标头)。
  2. 如果是POST方法,请阅读标题中的Content-Length并阅读Content-Length个字节。
  3. 如果是POST方法并且Content-Length标头不存在(最有可能发生),请先读取-1,这是EOF的信号}。

答案 1 :(得分:3)

我知道了:)谢谢你们的评论和答案......

     is = incoming.getInputStream(); // initiating inputStream
            os = incoming.getOutputStream(); // initiating outputStream

            in = new BufferedReader(new InputStreamReader(is)); // initiating
                                                                // bufferReader
            out = new DataOutputStream(os); // initiating DataOutputSteream

            RequestHandler rh = new RequestHandler(); // create a
                                                        // requestHandler
                                                        // object

            String line;
            while ((line = in.readLine()) != null) {
                if (line.equals("")) { // last line of request message
                                        // header is a
                                        // blank line (\r\n\r\n)
                    break; // quit while loop when last line of header is
                            // reached
                }

                // checking line if it has information about Content-Length
                // weather it has message body or not
                if (line.startsWith("Content-Length: ")) { // get the
                                                            // content-length
                    int index = line.indexOf(':') + 1;
                    String len = line.substring(index).trim();
                    length = Integer.parseInt(len);
                }

                request.append(line + "\n"); // append the request
            } // end of while to read headers

            // if there is Message body, go in to this loop
            if (length > 0) {
                int read;
                while ((read = in.read()) != -1) {
                    body.append((char) read);
                    if (body.length() == length)
                        break;
                }
            }

            request.append(body); // adding the body to request

答案 2 :(得分:0)

我想分享一下效果很好的代码:

private static String getClientRequest(Socket client) throws IOException, SocketException {
    System.out.println("Debug: got new client " + client.toString());
    BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8"));

    StringBuilder requestBuilder = new StringBuilder();
    String line;
    int contectLegnth = 0;
    
    while (!(line = br.readLine()).isBlank()) {
        requestBuilder.append(line + "\r\n");
        if (line.toLowerCase().startsWith("content-length")) {
            contectLegnth = Integer.parseInt(line.split(":")[1].trim());
        }
    }
    

    StringBuilder requestBodyBuilder = new StringBuilder();
    if (contectLegnth > 0) {
        int read;
        while ((read = br.read()) != -1) {
            requestBodyBuilder.append((char) read);
            if (requestBodyBuilder.length() == contectLegnth)
                break;
        }
        requestBuilder.append("\r\n" + requestBodyBuilder);
    }
   
    return requestBuilder.toString();
}