Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#(.net)下HTTP服务器保持活动套接字如何发送多个查询?_C#_Sockets_Http_Keep Alive - Fatal编程技术网

C#(.net)下HTTP服务器保持活动套接字如何发送多个查询?

C#(.net)下HTTP服务器保持活动套接字如何发送多个查询?,c#,sockets,http,keep-alive,C#,Sockets,Http,Keep Alive,诺布问题。 因此,我尝试在同一套接字上多次调用http服务器以获取资源: public void TryReuseSameSocket(){ var addr = Dns.GetHostAddresses("stackoverflow.com"); var socket = new Socket(SocketType.Stream, ProtocolType.Tcp); try {

诺布问题。 因此,我尝试在同一套接字上多次调用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();
            }
        }
public void TryReuseSameSocket(){
var addr=Dns.GetHostAddresses(“stackoverflow.com”);
var socket=新套接字(SocketType.Stream,ProtocolType.Tcp);
尝试
{
//我想我必须使用这个选项
socket.SetSocketOption(SocketOptionLevel.socket,SocketOptionName.KeepAlive,1);
插座连接(地址80);
var bigbuff=新字节[10000];
对于(变量i=0;i<20;i++)
{
//现在,我多次尝试在不关闭套接字的情况下调用某个URL
var buff=Encoding.ASCII.GetBytes(“GET/help/badges HTTP/1.1\r\nHost:stackoverflow.com\r\n连接:保持活动\r\n\r\n”);
socket.Send(buff);
var reciveCount=0;
var totalCount=0;
while(true)
{
reciveCount=socket.Receive(bigbuff);
totalCount+=reciveCount;
如果(0==reciveCount)中断;
}
//只有第一个调用将继续,所有其他调用都不会有结果
Assert.AreNotEqual(0,totalCount);
}
}
最后
{
socket.Dispose();
}
}
但只有第一个调用继续,所有其他调用在receive中都不返回任何数据


如何正确使用HTTP服务器的套接字。

您正在读取流,直到远程端关闭它。这是有道理的,在这一点之后,你将不会得到任何数据

您需要使服务器保持连接的活动状态。这是通过设置保持活动的HTTP头来完成的。你好像在那样做

使用HTTP保持活动状态,服务器将设置
内容长度
标题,告诉您要读取多少字节。准确读取那么多字节。之后,发送下一个请求


TCP保持有效性(
SocketOptionName.KeepAlive
)与HTTP保持有效性无关。删除该代码。

Thx。现在我找到了解决办法:

1) 别忘了检查套接字。可以决定的是流从读取到结束,检查流。读取(…)==0或接收(…)==0不是真正的事情

2) 不要信任Internet—有些服务器返回Keep Alive,但不是真的—连接已打开,但所有子请求都失败

3) 若读取逻辑看起来像这样,那个么讨论中的代码段正在工作

while (socket.Available != 0)
{
    socket.Receive(bigbuff);
}

4) 它并不总是100%好(你需要检查一些其他套接字的东西来控制读取),但在具有真正的Keep Alive支持的站点上,它工作得很好

另外,我的另一个答案中的错误是,您没有指示服务器保持连接的活动状态。正确的标题值为
保持活动状态
。这就是服务器关闭连接的原因。

无需重新发明轮子。使用WebClient、HttpWebRequest或HttpClient?使用
套接字而不是更高级别的抽象有什么特殊原因吗?其中有一些原因。我们已经实现了HttpWebRequest和HttpClient。1) 即使在使用quick Make http protocol parser的not keep alive socket上,我们也可以用更少的内存获得20%的性能提升(我们不需要处理http/S的所有功能,但在性能方面有需要-一些组件可以使用spider 2)我们尝试使用SuperSockets,但它仍然需要手工实现HttpProtocol,导致大量依赖项,对我们来说代码不太有用3)我们努力使用一些内部服务的REST API-s,因此在不增加HTTP解析层的情况下为它们提供更多本机握手/对话支持可能会更有效4)我们需要支持产品的.NET和Mono版本。因此,根据经验——仅在套接字层(特别是服务器端)上,我们有稳定的相同行为,在这些平台上,更多的外部类(WebClient等,尤其是HttpListener)似乎不相同。我们看到了其中的一些风险,所以我们决定尝试将我们的服务和客户端迁移到套接字层上的自写包装器。但是在网络内部能力不强会有一些问题。感谢您对TCP.KeepAlive的建议,虽然HTTP.KeepAlive在较低级别上是必需的。当然,这里您可以看到stackoverflow的特殊示例(这里的连接:Keep Alive被发送到服务器)。在工作代码中,我们使用套接字上的NetworkStream,我们编写请求,捕获内容长度或传输编码:分块,然后将流读到底。但它不起作用,只是第一个请求,所有后续的请求都没有返回。当NetworkStream被远程关闭时,您可以建议如何读取NetworkStream吗?现在,我们只需准确地读取内容长度,或者准确地读取“0”块之前的块。然后,我们尝试发送其他请求,流总是“不可用”。所以我们开始做“神奇的事情”-Thread.Sleep(10),在下一个请求之前添加NetworkStream的读取并控制lenght==0,检查响应头并查看服务器的头连接是否也保持活动状态。。。当read返回您已经丢失的0字节时,如何做好???@ФаГаМСаааа。服务器已关闭连接。在这一点上你无能为力。;如果看不到当前版本的代码,就很难判断您做错了什么。可用的代码并不表示将要提供多少数据。它表示缓冲了多少数据。这个数字可以随时增加。(3)中的重试循环没有完成任何操作。事实上,现在代码是不正确的,因为它将在某个点随机停止读取。只需删除循环。所有内容都不是100%,但检查可用的比检查接收长度更有效。“从头到尾阅读”并不是这个问题的主要目标,现在在工作代码中,它是由cross ch