我正在使用简单的锁定TCP套接字将消息发送到远程服务器,而我遇到的问题是,每条消息的发送时间都非常不同。
这里是我得到的(一些例子):
Bytes Sent: 217, Time: 34.3336 usec
Bytes Sent: 217, Time: 9.9107 usec
Bytes Sent: 226, Time: 20.1754 usec
Bytes Sent: 226, Time: 38.2271 usec
Bytes Sent: 217, Time: 33.6257 usec
Bytes Sent: 217, Time: 12.7424 usec
Bytes Sent: 217, Time: 21.5912 usec
Bytes Sent: 217, Time: 31.1480 usec
Bytes Sent: 218, Time: 28.3164 usec
Bytes Sent: 218, Time: 13.0963 usec
Bytes Sent: 218, Time: 82.8254 usec
Bytes Sent: 218, Time: 13.0963 usec
Bytes Sent: 227, Time: 30.7941 usec
Bytes Sent: 218, Time: 27.9624 usec
Bytes Sent: 216, Time: 2.1237 usec
Bytes Sent: 218, Time: 12.3884 usec
Bytes Sent: 227, Time: 31.1480 usec
Bytes Sent: 227, Time: 88.4887 usec
Bytes Sent: 218, Time: 93.0901 usec
Bytes Sent: 218, Time: 7.7870 usec
Bytes Sent: 218, Time: 28.3164 usec
Bytes Sent: 227, Time: 89.5505 usec
Bytes Sent: 218, Time: 84.2412 usec
Bytes Sent: 218, Time: 13.8042 usec
Bytes Sent: 227, Time: 99.4612 usec
Bytes Sent: 218, Time: 86.0110 usec
Bytes Sent: 218, Time: 12.3884 usec
Bytes Sent: 218, Time: 87.7807 usec
Bytes Sent: 216, Time: 3.5395 usec
Bytes Sent: 218, Time: 4.6014 usec
Bytes Sent: 218, Time: 36.1034 usec
Bytes Sent: 218, Time: 14.8661 usec
Bytes Sent: 218, Time: 24.0689 usec
Bytes Sent: 218, Time: 18.0517 usec
Bytes Sent: 227, Time: 24.4229 usec
有人知道为什么会发生这种情况吗?为什么要发送一条消息需要3个usec,而发送其他80个usec?有什么办法可以解决这个问题?
注意:我要存档的主要目标是尽快发送每封邮件。我不需要任何不合时宜的套接字,至少直到它们工作得更快为止。
关于我的工作的一些其他详细信息:
C ++,Visual Studio 2013
我如何打开:
...
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
...
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
...
我如何发送和计算时间:
...
LARGE_INTEGER cT;
QueryPerformanceCounter(&cT);
long long dT = cT.QuadPart;
iBytesSent = send(ConnectSocket, msgFinal, msgFinalLen, 0);
QueryPerformanceCounter(&cT);
dT = cT.QuadPart - dT;
...
此外,我还在从其他线程监听此套接字,我不知道这是否会影响发送:
iResult = recv(ConnectSocket, recvbuf, DEFAULT_BUFLEN, 0);
您的方法无效。您只测量将数据放入发送缓冲区所需的时间。如果有足够的空间,则根本没有网络运行。如果没有空间,则阻塞直到有空间,这取决于接收器读取已经存在的内容。因此,您看到的是,有时有空间,有时没有空间,这取决于接收器是否正在阅读并保持同步。
如果要测量往返时间,则需要发送一个时间戳并让对等方回显,然后在收到时将其与当前时间进行比较。
您没有测量消息“发送”所花费的时间,您正在测量将消息放入TCP发送缓冲区所花费的时间。那可能涉及内存分配,锁争用和许多其他事情。它还可能包括正在计划的另一个进程,这会导致您浪费时间。
您正在测量的是发送呼叫所花费的时间。它基本上是对套接字层的缓冲区的写(I / O)操作。
您的进程尝试执行I / O并被阻止-I / O完成后,守护程序将被唤醒。您看到的发送呼叫的时间差异包括:
i。实际写入时间。
ii。可中断的睡眠时间-因为调度程序不会在I / O完成后立即唤醒您的进程。可能还有另一个过程可能被唤醒。
调整:
i。尝试优化发送/接收窗口的大小。这是无需等待ACK即可发送的数据量。
访问:Setting TCP receive window in C and working with tcpdump in Linux
ii。传递给发送调用的缓冲区必须适合窗口大小。因此,tcp在实际刷新网络上的数据之前不会等待达到最佳大小。
iii。对于您的OS实现,类似于TCP_NODELAY的标志将有所帮助。
iv。重新调整守护程序的nice值,以便在阻塞I / O调用完成后立即将其唤醒。