【问题标题】:Why socket BeginSend would take too long为什么套接字 BeginSend 会花费太长时间
【发布时间】:2013-09-27 10:03:53
【问题描述】:

我有以下代码

        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 重现错误

进行以下修改: 客户=>

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

服务器=>

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 秒的超时时间

就像我们的一个装置中发生的那样

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

【问题讨论】:

  • 定义takes long,1 秒? 5 秒?
  • 这取决于客户和时间。有时我看到 3 有时 10 秒
  • 通常 BeginSend 的 IsCompleted 并不意味着字节被实际发送,而是它在 sendbuffer 中排队。
  • 没错!那为什么要把字节放入队列需要这么长时间?
  • 你可以在while循环中尝试这个getavailablethreads:msdn.microsoft.com/en-us/library/…

标签: c# sockets


【解决方案1】:

即使BeginSend 不会停止您的应用程序,它仍应具有与Send 相同的约束。 This 回答解释了为什么会出错(我已经解释过):

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

【讨论】:

  • 是的,你是对的。我在2014年找到了解决方案。实际上问题是接收机器被阻塞并且没有读取数据。所以我们不得不重新设计协议。抱歉,我没有在 Stackoverflow 中记录解决方案。
【解决方案2】:

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

【讨论】:

  • 是的,实际上正常的日志文件至少会打印一次“等待数据传输。超时1秒”
猜你喜欢
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-17
相关资源
最近更新 更多