使用C#(。net)下的HTTP服务器保持活动套接字如何发送多个查询?
Noob的问题。 所以我尝试这个代码在同一个套接字上多次调用http服务器资源:
public void TryReuseSameSocket(){ var addr = Dns.GetHostAddresses("stackoverflow.com"); var socket = new Socket(SocketType.Stream, ProtocolType.Tcp); try { // i thought that i must to use this option socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1); socket.Connect(addr, 80); var bigbuff = new byte[10000]; for (var i = 0; i < 20; i++) { //now i try to call some URL many times without socket closing var buff = Encoding.ASCII.GetBytes("GET /help/badges HTTP/1.1\r\nHost: stackoverflow.com\r\nConnection: Keep-Alive\r\n\r\n"); socket.Send(buff); var reciveCount = 0; var totalCount = 0; while (true) { reciveCount = socket.Receive(bigbuff); totalCount += reciveCount; if (0 == reciveCount) break; } //only first call will proceed, all others will not have a result Assert.AreNotEqual(0,totalCount); } } finally { socket.Dispose(); } }
但只有第一次呼叫继续,所有其他人都没有返回任何数据。
如何正确地重用套接字与HTTP服务器。
您正在读取流,直到它被远程端关闭。 有意义的是,在那之后你将无法获得任何数据。
您需要使服务器保持连接活动。 这是通过设置保持活动的HTTP标头来完成的。 你好像在做那件事。
在HTTP保持活动状态下,服务器将设置Content-Length
标头以告诉您要读取多少字节。 准确读取那么多字节。 之后,发送下一个请求。
TCP keep SocketOptionName.KeepAlive
( SocketOptionName.KeepAlive
)与HTTP keep SocketOptionName.KeepAlive
无关。 删除该代码。
另外,在我的另一个答案中的错误,你没有指示服务器保持连接活着。 正确的标头值是keep-alive
。 这就是服务器关闭连接的原因。
谢谢。 现在我找到了解决方案:
1)不要忘记检查socket.Available决定是流读取结束,检查stream.Read(…)== 0或Recive(…)== 0不是真实的东西
2)不信任Internet – 某些服务器返回Keep-Alive但不是真的 – 连接已打开,但所有子请求都失败
3)如果阅读逻辑看起来像是有问题的片段正在工作
while (socket.Available != 0) { socket.Receive(bigbuff); }
4)它不是100%总是好的(你需要检查一些其他套接字的东西来控制阅读),但是在真正的Keep-Alive支持的网站上它运作良好。