Noob question. So i try this code to call http server for resource many times on same socket:
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();
}
}
But only first call proceed, all others return no data at all in recieve.
How to reuse socket with HTTP server correctly.
You are reading the stream until it is closed by the remote side. It makes sense that after that point you won't get any data.
You need to make the server keep the connection alive. This is done by setting a keep alive HTTP header. You seem to be doing that.
With HTTP keep alive the server will set the Content-Length
header to tell you how many bytes to read. Read exactly that many bytes. After that, send the next request.
TCP keep alives (SocketOptionName.KeepAlive
) have nothing to do with HTTP keep alives. Remove that code.
In addition the mistakes in my other answer you are not instructing the server to keep the connection alive. The proper header value is keep-alive
. That's why the server closes the connection.
Thx. Now I have found solution:
1) Don't forget check socket.Available to decide is stream read to end, checking of stream.Read(...) == 0 or Recive(...)==0 is not real thing
2) Don't trust Internet - some servers return Keep-Alive but it's not true - connection is opened, but all subrequests fails
3) Snippet in question is working if reading logic will looks like
while (socket.Available != 0)
{
socket.Receive(bigbuff);
}
4) It's not 100% always good (u need check some other socket things to controll reading), but on sites with real Keep-Alive support it works well.
来源:https://stackoverflow.com/questions/25612557/keep-alive-socket-with-http-server-under-c-sharp-net-how-to-send-several-quer