首先,当我说http协议(protocol)混合字符流和字节流时,我的意思是请求头是字符流和请求体是字节流(由 content-length 指定),它们由一个空行分隔。
这种设计使得http的实现更加困难。例如,如果你使用java实现一个http服务器,你不能使用这样的代码,因为BufferedReader会缓冲一些字节来读取一行。
InputStream stream=socket.getInputStream();
BufferedReader reader=new BufferedReader(new InputStreamReader(stream));
String line;
while( !(line=reader.readLine()).equals("") ){
//do something with line
}
//from stream to read content-length bytes
stream.read(...)
如果使用前两个字节指定请求头的长度而不是使用空行,那么http协议(protocol)的实现会更容易。
最佳答案
这不仅仅是糟糕的设计……它已经坏掉了。 BufferedReader
可能会将请求主体的第一部分读入其缓冲区。所以当你最后从流中读取时,你不会得到所有的 body 。
一旦你包装了一个 InputStream
你就不应该直接使用它......特别是如果包装器做缓冲。
实现这一点的最佳方法是使用现有的 HTTP 服务器端实现。 Apache HTTP 组件库是一个值得考虑的好选择。
如果您必须自己实现,那么简单的解决方案是:
- 将
InputStream
包装在BufferedInputStream
中。 - 使用
BufferedInputStream
一次读取一个字节的标题行并构建行并自行转换为字符串。 - 使用
BufferedInputStream
读取正文。
I feel that the stupid design of HTTP protocol makes the
java.io
library useless.
我不会这么说。问题是 HTTP 协议(protocol)可能需要客户端在消息中途切换它解释请求或响应消息的字符/字节的方式。但仔细想想,这并不是一件不合理的事情。备选方案是:
- 发送单独的消息,这会增加协议(protocol)开销,或者
- 将请求/响应行和 header 编码并发送为字节而不是字符。
我们真正拥有的是一个棘手的用例,它太不寻常以至于无法在通用 java.io
库中得到支持。一个协议(protocol)支持库会处理这个问题……如果你能使用的话。
关于java - 你认为http协议(protocol)混合字符流和字节流不是一个好的设计吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7545814/