C ++ TCP套接字发送速度

时间:2015-08-18 07:44:11

标签: c++ sockets raw-sockets

我正在使用简单的锁定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);

3 个答案:

答案 0 :(得分:3)

您的方法无效。您只测量将数据放入发送缓冲区所需的时间。如果有空间,则根本没有网络操作。如果没有空间,你会阻止,直到有空间,这取决于接收器读取已经存在的东西。所以你所看到的是,有时会有空间而有时却没有,这取决于接收器是否正在阅读和保持。

如果你想测量往返时间,你需要发送一个时间戳并让对等人回复它,然后当你收到时将它与当前时间进行比较。

答案 1 :(得分:1)

您没有测量消息被“发送”所花费的时间,您正在测量消息进入TCP发送缓冲区所需的时间。这可能涉及内存分配,锁争用和许多其他事情。它还可以包括正在安排的另一个进程,导致您丢失时间片。

答案 2 :(得分:0)

您测量的是发送电话所需的时间。 它基本上是对套接字层缓冲区的写入(I / O)操作。

您的进程尝试进行i / o并被阻止 - 一旦i / o完成,守护进程就会被唤醒。您看到发送呼叫的时间差异包括:

我。实际写入时间。

II。可中断的休眠时间 - 因为调度程序在I / O完成后不会立即唤醒您的进程。可能还有另一个可能被唤醒的过程。

调整菜谱方案:

我。尝试优化发送/接收窗口大小。这是可以在不等待ACK的情况下发送的数据量。

访问:Setting TCP receive window in C and working with tcpdump in Linux

II。传递给发送调用的缓冲区必须符合窗口大小。因此,在实际刷新网络上的数据之前,tcp不会等待达到OPTIMUM大小。

III。您的操作系统实现类似于TCP_NODELAY的标志将有所帮助。

IV。重新调整守护程序的nice值,以便在阻塞I / O调用完成后立即唤醒它。