2012-11-12 29 views
0

我们有一个应用程序,通过TCP套接字发送数据。我们为此使用8个TCP连接。套接字发送和接收在后台线程中调用。只有一个线程遍历套接字数组来发送数据(顺序)。线程中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 
} 

一切工作正常,得到的数据传输,但有时它只是时间太长。 在检查日志时,我发现在大多数情况下,发送者线程工作得很好,但有时候,'发送'呼叫之前和之后在时间戳(有时超过一秒)方面存在巨大延迟。

所有发送和接收操作都发生在工作线程中。在发送呼叫之前/在发送呼叫之前是否需要抢占线程?我可以在发送呼叫之前避免抢占线程吗?还是说接收线程在发送准备好更多的数据时没有收到套接字上的数据,因此会导致延迟?

如何优化它,因为发送数据花费的时间太长?

谢谢

+0

您可以使用像[Wireshark](http://www.wireshark.org/)这样的工具来检查是否有任何延迟低于您的应用程序。 – Default

+0

你的套接字是否阻塞('O_NONBLOCK')?如果不是,直到所有的数据已被本地TCP堆栈接受(这只与线路上的内容有关,可能是立即的或可能需要一些时间),send()调用才会返回。包括wireshark/tcpdump跟踪可能会有所帮助。 –

回答

1

您应该使用非阻塞套接字发送。可能发生的事情是,一个(或多个)不能立即发送,所以它会等待,直到它可以发送一些数据,也许缓冲区满或任何。

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

+0

但他说,插座是在后台线程 – Default

+0

@默认,他说发送延迟(块),只有一个线程。 – aaronps

0

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

+2

从设计的角度来看,你应该做的是在所有的套接字上同时做两个“选择”,并且在循环中写入并读取每一个准备好的数据。如果所有套接字都没有准备好,这将阻止旋转轮询... – mark