简体   繁体   English

建议从HTTP服务器中读取套接字的方法

[英]Recommended way to read from socket in HTTP server

As a challenge I have implemented a basic web server in Java. 作为一项挑战,我已经用Java实现了一个基本的Web服务器。 When I open the raw InputStream I immediately go into a blocking read which reads the entire 400 or bytes of the HTTP request into a byte array. 当我打开原始InputStream我立即进入阻塞读取,该读取将HTTP请求的整个400或字节读入字节数组。 This works, however I then do not check for any more data and simply close the socket after sending a response. 这是有效的,但是我不再检查任何数据,只是在发送响应后关闭套接字。

I'm wondering is there a more robust way to do this so as not to miss any data from the client. 我想知道是否有更强大的方法来做到这一点,以免错过来自客户端的任何数据。 I thought of reading one byte at a time until read returned end of stream. 我想一次读取一个字节,直到read返回流的结尾。 However it instead sometimes blocks when there is no more data and confusingly the JavaDocs for public abtract int InputStream.read() says: 然而,它有时会在没有更多数据时阻塞,并且令人困惑的是JavaDocs for public abtract int InputStream.read()说:

If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

So it implies that two things can happen if the end of stream is reached: returning -1 and blocking. 所以它意味着如果到达流的末尾会发生两件事:返回-1和阻塞。 I am seeing blocking. 我看到了阻塞。

My question is, with a protocol like HTTP, how should you read from the socket and how do you know when that's all the data you'll be getting in this connection? 我的问题是,使用像HTTP这样的协议,你应该如何从套接字读取,你怎么知道这个连接中你将获得的所有数据?

The JavaDoc you quote does not imply that two things can happen if the end of stream is reached. 您引用的JavaDoc 并不意味着如果到达流末尾会发生两件事。 It doesn't say read blocks when the end of the stream is detected, but until the end of stream is detected. 检测到流的末尾 ,它不会说读取块,而是直到检测到流的末尾。 Once it is detected, -1 is returned. 一旦检测到,返回-1。

This explains the behavior you're observing: no end of stream is detected and read is blocked. 这解释了您正在观察的行为:未检测到流的末尾,并且阻止了读取。 The end of stream is detected once the connection is closed, but it isn't closed since the client doesn't close the connection immediately after sending a request. 一旦连接关闭,就会检测到流的末尾,但由于客户端在发送请求后没有立即关闭连接,因此它不会关闭。 It must keep it open to receive the reply. 必须保持开放才能收到回复。

In order to ensure you receive all data from the client you should parse their HTTP request until you see the end of header (double newline) plus whatever amount of data they have specified in the header (if any). 为了确保您从客户端接收所有数据,您应该解析其HTTP请求,直到您看到标题的结尾(双换行)加上它们在标题中指定的任何数据量(如果有)。

If you'd like to avoid blocking have a look at java.nio and channels ( SocketChannel in particular). 如果您想避免阻塞,请查看java.niochannels (特别是SocketChannel )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM