为什么socket BeginSend需要太长时间

时间:2013-09-27 10:03:53

标签: c# sockets

我有以下代码

        byte[] bytes = Encoding.Default.GetBytes(data);
        IAsyncResult res = socket.BeginSend(bytes, 0, bytes.Length, 0, new AsyncCallback(SendCallback), socket);
        int waitingCounter = 0;
        while (!res.IsCompleted && waitingCounter<10)
        {
            if (Tracing.TraceInfo) Tracing.WriteLine("Waiting for data to be transmited. Give a timeout of 1 second", _traceName);
            Thread.Sleep(1 * 1000);
            waitingCounter++;
        }

此代码已安装在许多机器中,但在某些情况下,条件res.IsCompleted需要很长时间才能生效。

原因与网络有关,可能是防火墙,代理?或客户端(太慢)或服务器?

我无法重现这种情况。

修改:我尝试使用asynchronous client and a synchronous server

重现错误

进行以下修改: 客户=&GT;

while (true) { 
        Send(client, "This is a test<EOF>");
        sendDone.WaitOne();
}

服务器=&GT;

while (true){
         Console.WriteLine("Waiting for a connection...");
         // Program is suspended while waiting for an incoming connection.
         Socket handler = listener.Accept();
         data = null;

         // Show the data on the console.
         Console.WriteLine("Text received : {0}", data);

         handler.Shutdown(SocketShutdown.Both);
         handler.Close();
}

在第二个Send()中,我收到套接字异常。什么是正常的,因为服务器没有读取数据。 但实际上我想要重现的是:

等待数据传输。超时1秒 等待数据传输。超时1秒 等待数据传输。超时1秒 等待数据传输。超时1秒 等待数据传输。超时1秒

正如我们的一个装置中所发生的那样

编辑: 答案从这个问题中消失了!!!

2 个答案:

答案 0 :(得分:0)

不要忘记第一次检查res.IsCompleted时,您总是等待下一次检查。

答案 1 :(得分:0)

即使BeginSend不会拖延您的应用程序,它仍应具有与Send相同的约束。 This回答解释了为什么事情可能出错(我已经转述):

  

对于您的应用程序,TCP缓冲区,网络和本地   发送TCP缓冲区是一个很大的缓冲区。 如果远程应用程序获取   延迟从TCP缓冲区读取新字节,最终你的   本地TCP缓冲区最终将(几乎)满。发送不会   完成,直到TCP缓冲区有足够的空间来存储有效负载   你正试图发送。