UDP收发buffer尺寸对收发包流量的影响

下午验证一个高流量发包问题时,发现了一个值得记录的问题:socket的收发buffer尺寸是会影响收发包的效率的,高流量通讯时,若socket的收发buffer尺寸过小会一定程度降低收发包效率。

自己先分别获取了一下Windows/Linux系统中默认的收发包尺寸值
在x86 Win7环境里实际程序验证结果为

$ ./sockopt.exe
UDP socket options:
        receive buffer: 0x2000
        send buffer: 0x2000
TCP socket options:
        receive buffer: 0x2000
        send buffer: 0x2000

只有8KiB。
在cubieboard2环境(Linux cubieboard2 3.4.79 #1 SMP PREEMPT Fri Dec 19 17:51:20 CST 2014 armv7l GNU/Linux)里程序验证结果为

cubie@cubieboard2:~$ ./sockopt_linux
UDP socket options:
        receive buffer: 0x28000
        send buffer: 0x28000
TCP socket options:
        receive buffer: 0x15554
        send buffer: 0x4000

可见在Windows下默认的socket收发buffer尺寸都比较小,后续的结果表明,对应对收发包的效率影响更为明显。实际测试代码如下

 1 #include "net/udp_peer.h"
 2 #include "util/log.h"
 3 
 4 #include <stdlib.h>
 5 #include <string.h>
 6 
 7 static inetaddr_t addr;
 8 static char data[64000];
 9 
10 static void on_message(udp_peer_t *peer, void *message, unsigned size, void* userdata, const inetaddr_t *peer_addr)
11 {
12     return;
13 }
14 
15 static void on_writable(udp_peer_t *peer, void* userdata)
16 {
17     udp_peer_send(peer, data, sizeof(data), &addr);
18 
19     return;
20 }
21 
22 int main(int argc, char *argv[])
23 {
24     loop_t *loop;
25     udp_peer_t *peer;
26     
27     #ifdef WIN32
28     WSADATA wsa_data;
29     WSAStartup(MAKEWORD(2, 2), &wsa_data);
30     #endif
31     
32     log_setlevel(LOG_LEVEL_INFO);
33     
34     inetaddr_initbyipport(&addr, argv[1], 1994);
35     
36     loop = loop_new(64);
37     peer = udp_peer_new(loop, "0.0.0.0", 1994, on_message, on_writable, NULL);
38     udp_peer_expand_send_buffer(peer, (2*1024*1024));
39     /* udp_peer_expand_recv_buffer(peer, (2*1024*1024)); */
40     
41     loop_loop(loop);
42     
43     udp_peer_destroy(peer);
44     loop_destroy(loop);
45     
46     #ifdef WIN32
47     WSACleanup();
48     #endif
49     
50     return 0;
51 }

在cubieboard和Windows系统上互相通过UDP进行快速收发包,通过不同方式调节socket收发包buffer尺寸,并进行流量统计,最终得出的结果分别如下(在Windows上利用NetWorx进行流量统计)
1,保持默认的收发buffer尺寸,进行快速发包,直至将百兆带宽打满,流量图如下

2,仅将两端发包buffer尺寸增加2MiB,同样将百兆带宽打满,流量图如下

3,将两端收发包都增加2MiB,将百兆带宽打满,流量图下

可见将socket的发包buffer增大之后,在Windows下发包流量有明显的提升(峰值增加了大概2MiB,约20%)。
自己分析认为这是因为默认情况下Windows下socket发包Buffer较小,发包流量高时,出现发包Buffer满的情况概率较高,而使得后续的sendto()调用失败的概率也对应升高,从而就降低了发包效率,在此处就形成了一个瓶颈,限制了发包流量的进一步升高。而增大socket的发包Buffer之后,此处的限制得到解除,而使得最终的限制就落在网口的最大速率带宽上。

~~ end ~~

原文地址:https://www.cnblogs.com/lanyuliuyun/p/4732567.html