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

时间:2012-03-03 01:41:42

标签: java http sockets networking tcp

作为一项挑战,我已经用Java实现了一个基本的Web服务器。当我打开原始InputStream时,我立即进入阻塞读取,该读取将HTTP请求的整个400或字节读入字节数组。这有效,但是我不再检查任何数据,只是在发送响应后关闭套接字。

我想知道是否有更强大的方法来做到这一点,以免错过来自客户端的任何数据。我想一次读取一个字节,直到read返回流末尾。但是,它有时会在没有更多数据时阻塞,并且public abtract int InputStream.read()的JavaDocs混淆地说:

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.

所以它意味着如果到达流的末尾会发生两件事:返回-1和阻塞。我看到了封锁。

我的问题是,使用像HTTP这样的协议,你应该如何从套接字中读取内容?你怎么知道这个连接中你将获得的所有数据?

1 个答案:

答案 0 :(得分:7)

你引用的JavaDoc 暗示如果到达流的末尾会发生两件事。它没有说在检测到流结束时读取块,而是直到检测到流的末尾。一旦检测到,则返回-1。

这解释了您正在观察的行为:未检测到流的末尾,并且阻止了读取。一旦连接关闭,就会检测到流的末尾,但由于客户端在发送请求后没有立即关闭连接,因此它不会关闭。它必须保持开放才能收到回复。

为了确保您从客户端接收所有数据,您应解析其HTTP请求,直到您看到标题的结尾(双换行)加上它们在标题中指定的任何数据量(如果有)。

如果您想避免阻止,请查看java.niochannels(特别是SocketChannel)。