【问题标题】:Strange behaviour with TCP sockets in thread线程中 TCP 套接字的奇怪行为
【发布时间】:2012-11-12 13:01:57
【问题描述】:

我们有一个应用程序,我们通过 TCP 套接字发送数据。为此,我们使用 8 个 TCP 连接。套接字发送和接收在后台线程中调用。只有一个线程遍历套接字数组以通过所有套接字发送数据(顺序)。

发送者线程中的代码类似于:

for(i = 0; i < 8; i++) {

    nBytesWrriten = send (tcpsock[i], data2, nleft, 0))
    //error handling and process more data

}

接收线程是这样的:

for(i = 0; i < 8; i++) {

    sz[i] = recv (tcpsock[i], data, MAX_UDT_SIZE, 0);
    //process data
}

一切正常,数据已传输,但有时需要的时间太长。 在检查日志时,我发现在大多数情况下,发送者线程工作得很好,但有时,在“发送”调用之前和之后的时间戳会有很大的延迟(有时超过一秒)。

所有发送和接收操作都在工作线程中进行。这与在发送调用之前/期间抢占线程有关吗?我可以避免在发送调用之前抢占线程吗?或者是接收线程在发送准备好更多数据的同时还没有收到套接字上的数据,因此导致延迟?

由于发送数据花费的时间太长,我该如何优化?

谢谢

【问题讨论】:

  • 您可以使用Wireshark 之类的工具来检查是否存在比您的应用程序更低级别的延迟。
  • 您的套接字是否无阻塞 (O_NONBLOCK)?如果没有,send() 调用将不会返回,直到所有数据都被本地 TCP 堆栈接受(这仅与线路上的内容有些相关,可能是即时的,也可能需要一些时间)。包括一个 wireshark/tcpdump 跟踪可能会有所帮助。

标签: c++ sockets tcp winsock


【解决方案1】:

您应该使用非阻塞套接字进行发送。可能发生的情况是一个(或多个)无法立即发送,因此它会等待直到它可以发送一些数据,可能是缓冲区已满或其他什么。

使用非阻塞套接字它不会停止,但您必须检查数据是否未发送到某些套接字并稍后重试。

【讨论】:

  • @Default 他说发送延迟(块)并且只有一个线程。
【解决方案2】:

在发送之前在每个套接字上执行select 以查看您是否可以在不阻塞的情况下进行写入,否则您将阻塞其他套接字上的发送。你会想在读取端做同样的事情,否则一个缺乏可读性可能会阻止其他人的可用读取。

【讨论】:

  • 从设计的角度来看,你应该做的是一次在所有的套接字上做一个select,在两端,然后对每个准备好的进行循环写入和读取。如果所有套接字都没有准备好,这将阻止自旋轮询......
猜你喜欢
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多