建议从HTTP服务器中读取套接字的方法 [英] Recommended way to read from socket in HTTP server

查看:196
本文介绍了建议从HTTP服务器中读取套接字的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As a challenge I have implemented a basic web server in Java. 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. This works, however I then do not check for any more data and simply close the socket after sending a response.

我想知道是否有更强大的方法可以做这样可以不遗漏客户的任何数据。我想过一次读取一个字节,直到读取返回流结束。然而,它有时会在没有更多数据时阻塞,并且令人困惑地将JavaDocs用于 public abtract int InputStream.read()说:

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. However it instead sometimes blocks when there is no more data and confusingly the JavaDocs for public abtract int InputStream.read() says:

如果由于到达流末尾没有可用字节,则返回值-1。此方法将阻塞,直到输入数据可用,检测到流的末尾或抛出异常。

因此它意味着两个如果到达流的末尾会发生一些事情:返回-1并阻塞。我看到了阻塞。

So it implies that two things can happen if the end of stream is reached: returning -1 and blocking. I am seeing blocking.

我的问题是,使用像HTTP这样的协议,你应该如何从套接字读取,你怎么知道什么时候这就是所有的数据你会得到这个连接吗?

推荐答案

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

The JavaDoc you quote does not imply that two things can happen if the end of stream is reached. 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.

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

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.

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

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).

如果您想避免阻塞,请查看 java.nio中 频道SocketChannel

If you'd like to avoid blocking have a look at java.nio and channels (SocketChannel in particular).

这篇关于建议从HTTP服务器中读取套接字的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆