【问题标题】:C++ TCP socket sending speedC++ TCP 套接字发送速度
【发布时间】:2015-08-18 07:44:11
【问题描述】:

我正在使用简单的锁定 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 微秒才能发送,而其他消息需要 80 微秒?
有没有办法解决这个问题?

注意:我要归档的主要目标是尽可能快地发送每条消息。我不需要任何同步套接字,至少在它们工作得更快之前是这样。

关于我的工作的一些额外细节:

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 是一种流协议。它没有“消息”的概念,您正在发送一个字节流。这意味着,例如,接收方可能会以不同大小的块接收数据,而不是您发送的数据。 TCP 只保证,另一端以相同的顺序接收相同的字节,没有任何丢失(或者如果重新发送失败则断开连接)。
  • 我不认为你在测量发送时间,你只是在测量send 通话时间。
  • 如果您希望消息尽快发送出去,也可以设置 TCP_NODELAY。 msdn.microsoft.com/en-us/library/windows/desktop/…
  • @dau_sama 除了这实际上会使发送过程变慢send 操作在发送数据包时比不发送数据包时花费更长的时间。设置 TCP_NODELAY 将使每个发送操作发送一个数据包。

标签: c++ sockets raw-sockets


【解决方案1】:

您的方法无效。您只是在测量将数据放入发送缓冲区需要多长时间。如果有空间,根本就没有网络操作。如果没有空间,你会阻塞直到有空间,这取决于接收器读取已经存在的内容。所以你看到的是,有时有空间,有时没有,这取决于接收器是否正在阅读和跟上。

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

【讨论】:

  • 有什么方法可以监视和控制发送的内容和缓冲区中的内容?也许我可以指定任何建议/选项/配置以使发送过程更快、更稳定?或者如果可能的话,它可能有助于增加缓冲区大小? :)
  • @Artem 有一个简单的方法——不要使用 TCP。 TCP 是一种流协议,它有一些保证和缺点,如果您尝试使用它来发送快速的小数据包,您会觉得很麻烦。 UDP 可能是更好的选择(尽管您可能希望使用一些更高级别的库来处理这个问题)。但是忘记秒。在任何合理的情况下,您仍在查看 毫秒秒 - 在精心设计的 LAN 上几乎不可能低于毫秒,但在互联网上则完全愚蠢。
  • @Artem 我已经提出了正确的方法。缓冲区中的内容与否无关紧要。
  • 如果你使用终端的 echo 来代替,那将是几乎相同的性能,所以我不必编写自己的代码来测试?
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    我。实际写入时间。

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

    调整:

    我。尝试优化发送/接收窗口大小。这是无需等待 ACK 即可发送的数据量。

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

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

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

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

    【讨论】:

    • 谢谢,我想澄清一点。 “iv. 重新调整守护程序的 nice 值,以便在阻塞 I/O 调用完成后立即唤醒它。”您能否解释一下“重新调整好的值”是什么意思以及如何进行这种“重新调整”?
    • 请访问:stackoverflow.com/questions/7618291/…。这将有助于引起调度员的注意。
    猜你喜欢
    • 1970-01-01
    • 2016-01-11
    • 2017-04-24
    • 2022-08-22
    • 2014-05-10
    • 2015-02-07
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多