我一直在为我的某些应用程序编写小型特定目的HTTP服务器,并且我注意到,如果您在之前read()
所有可用数据都未正确发送字节。例如,read()
后荷兰国际集团仅的请求线(GET/HTTP/1.1\r\n
)通过我的浏览器发送的,我write()
:在读取所有数据之前写入TCP套接字的行为
HTTP/1.1 200 OK\r\n
Connection: close\r\r
Content-Type: text/html\r\n
\r\n
(some HTML stuff)
此write()
的Wireshark的捕获:
'\n'
字节和Content-Type
头消失了! (Wireshark在HTTP头部分总是显示'\n'
字节,如果它们存在)
而浏览器不显示HTML内容。
所以我不应该在read()
之前write()
一切?这是TCP标准吗?
编辑1:加入我的C++代码,发送的东西:
string header =
"HTTP/1.1 200 OK\r\n"
"Connection: close\r\r"
"Content-Type: text/html\r\n"
"\r\n"
;
write(sd, header.c_str(), header.size()); // from unistd.h
FILE* fp = fopen("index.html", "rb");
char by;
while (fread(&by,1,1,fp) == 1) write(sd,&by,1);
fclose(fp);
编辑2:嗯,@selbie指出一个错字... "Connection: close\r\r"
。修复之后,行为发生了变化,变得不那么可怕:write()
实际上根本不发送数据。现在,Wireshark只显示请求!没有回应(来自我的write()
)被捕获。
编辑3:由于@usr的建议,我写了一个小测试客户端...当服务器read()
一切都好总是接收所有的HTTP有效载荷之前write()
ING,客户端。当服务器write()
s之前read()
ing客户端发送的头,客户端永不接收整个HTTP负载。我做了很多测试!read()
当后
服务器write()
小号荷兰国际集团标题:
HTTP/1.1 200 OK\r\n
Connection: close\r\n
Content-Type: text/html\r\n
\r\n
<form>\n
<input type="text" name="field1" />\n
<input type="text" name="field2" />\n
<input type="submit" value="send" />\n
</form>\n
当服务器write()
小号以前read()
荷兰国际集团标题:
HTTP/1.1 200 OK\r\n
Connection: close\r\n
Content-Type: text/html\r\n
\r\n
<form>\n
<input type="text" name="field1" />\n
<input
和:
和:
HTTP/1.1 200 OK\r\n
Connection: close\r\n
Content-Type: text/html\r\n
\r\n
<form>\n
<input type="tex
我跑客户喜欢与各设置50次。
为什么会发生这种情况?它有是内核的东西...
编辑4:另一件事,我注意到做这些测试...Wireshak 总是显示请求和响应,如果服务器read()
的标题,但总是只显示请求,如果服务器不read()
标题。严重的是,这与TCP有关。
您的连接标头以两个CR而不是CR-LF终止,这可能会让wireshark和浏览器感到困惑。 – rici
我修正了这个问题,请参阅编辑。 – matheuscscp
你在这里有另一个潜在的错误。你似乎没有检查你的'read'和'write'调用的返回值。由于各种原因,这些调用可能会失败并返回-1。更重要的是 - 读/写调用可以返回一个值来指示部分数据。 – selbie