socket tcp缓冲区大小的默认值、最大值

Author:阿冬哥

Created:2013-4-17

Blog:http://blog.csdn.net/c359719435/

Copyright 2013 阿冬哥 http://blog.csdn.net/c359719435/

使用以及转载请注明出处

1 设置socket tcp缓冲区大小的疑惑

疑惑1:通过setsockopt设置SO_SNDBUF、SO_RCVBUF这连个默认缓冲区的值,再用getsockopt获取设置的值,发现返回值是设置值的两倍。为什么?

通过网上查找,看到linux的内核代码/usr/src/linux-2.6.13.2/net/core/sock.c,找到sock_setsockopt这个函数的这段代码:

case SO_SNDBUF:

/* Don‘t error on this BSD doesn‘t and if you think

about it this is right. Otherwise apps have to

play ‘guess the biggest size‘ games. RCVBUF/SNDBUF

are treated in BSD as hints */

if (val > sysctl_wmem_max)//val是我们想设置的缓冲区大小的值

val = sysctl_wmem_max;//大于最大值,则val值设置成最大值

sk->sk_userlocks |= SOCK_SNDBUF_LOCK;

if ((val * 2) < SOCK_MIN_SNDBUF)//val的两倍小于最小值,则设置成最小值

sk->sk_sndbuf = SOCK_MIN_SNDBUF;

else

sk->sk_sndbuf = val * 2;//val的两倍大于最小值,则设置成val值的两倍

/*

*      Wake up sending tasks if we

*      upped the value.

*/

sk->sk_write_space(sk);

break;

case SO_RCVBUF:

/* Don‘t error on this BSD doesn‘t and if you think

about it this is right. Otherwise apps have to

play ‘guess the biggest size‘ games. RCVBUF/SNDBUF

are treated in BSD as hints */

if (val > sysctl_rmem_max)

val = sysctl_rmem_max;

sk->sk_userlocks |= SOCK_RCVBUF_LOCK;

/* FIXME: is this lower bound the right one? */

if ((val * 2) < SOCK_MIN_RCVBUF)

sk->sk_rcvbuf = SOCK_MIN_RCVBUF;

else

sk->sk_rcvbuf = val * 2;

break;

从上述代码可以看出:(1)当设置的值val > 最大值sysctl_wmem_max,则设置为最大值的2倍:2*sysctl_wmem_max;

(2)当设置的值的两倍val*2 > 最小值,则设置成最小值:SOCK_MIN_SNDBUF;

(3)当设置的值val < 最大值sysctl_wmem_max,且 val*2 > SOCK_MIN_SNDBUF, 则设置成2*val。

查看linux 手册:

            SO_RCVBUF:

                    Sets or gets the maximum socket receive buffer in bytes.

                    The kernel doubles this value (to allow space for bookkeeping overhead) when it                     is set using setsockopt(2),

                    and this doubled value is returned by getsockopt(2).

The default value is set by the /proc/sys/net/core/rmem_default file,

                    and the maximum allowed value is set by the /proc/sys/net/core/rmem_max file.

                    The minimum (doubled) value for this option is 256.

查看我的主机Linux 2.6.6 :/proc/sys/net/core/rmem_max:

4194304 //4M

查看/proc/sys/net/core/wmem_max:

8388608   //8M

所以,能设置的接收缓冲区的最大值是8M,发送缓冲区的最大值是16M。

疑惑2:为什么要有2倍这样的一个内核设置呢?我的理解是,用户在设置这个值的时候,可能只考虑到数据的大小,没有考虑数据封包的字节开销。所以将这个值设置成两倍。

注:overhead,在计算机网络的帧结构中,除了有用数据以外,还有很多控制信息,这些控制信息用来保证通信的完成。这些控制信息被称作系统开销。

2 tcp缓冲区大小的默认值

建立一个socket,通过getsockopt获取缓冲区的值如下:

发送缓冲区大小:SNDBufSize = 16384

接收缓冲区大小:RCVBufSize = 87380

疑惑3:linux手册中,接收缓冲区的默认值保存在/proc/sys/net/core/rmem_default,发送缓冲区保存在/proc/sys/net/core/wmem_default。

[[email protected]_netstorage core]# cat /proc/sys/net/core/rmem_default

1048576

[[email protected]_netstorage core]# cat /proc/sys/net/core/wmem_default

512488

可知,接收缓冲区的默认值是:1048576,1M。发送缓冲区的默认值是:512488,512K。为什么建立一个socket时得到的默认值是87380、16384???

进一步查阅资料发现, linux下socket缓冲区大小的默认值在/proc虚拟文件系统中有配置。分别在一下两个文件中:

/proc/sys/net/ipv4/tcp_wmem

[[email protected]_netstorage core]# cat /proc/sys/net/ipv4/tcp_wmem

4096    16384   131072  //第一个表示最小值,第二个表示默认值,第三个表示最大值。

/proc/sys/net/ipv4/tcp_rmem

[[email protected]_netstorage core]# cat /proc/sys/net/ipv4/tcp_rmem

4096    87380   174760

由此可见,新建socket,选取的默认值都是从这两个文件中读取的。可以通过更改这两个文件中的值进行调优,但是最可靠的方法还是在程序中调用setsockopt进行设置。通过setsockopt的设置,能设置的接收缓冲区的最大值是8M,发送缓冲区的最大值是16M(Linux 2.6.6中)。

原文地址:https://www.cnblogs.com/x_wukong/p/8444557.html

时间: 2024-08-29 12:37:35

socket tcp缓冲区大小的默认值、最大值的相关文章

TCP缓冲区大小及限制

TCP输出 下图展示了应用进程写数据到TCP套接口的过程. 每一个TCP套接口有一个发送缓冲区,我们可以用SO_SNDBUF套接口选项来改变这个缓冲区的大小.当应用程序调用write时,内核从应用程序进程的缓冲区中拷贝所有数据到套接口的发送缓冲区.如果套接口的发送缓冲区容不下应用程序的所有数据(或是应用程序的缓冲区大于套接口发送缓冲区,或是套接口发送缓冲区还有其他数据),应用进程将被挂起(睡眠).这里假设套接口是阻塞的,它是通常的缺省设置(还有非阻塞的套接口).内核将不从write系统调用返回,

路由器缓冲区大小为什么如此重要

一台路由器缓冲区稍微大一点,你知道会带来多大的益处吗?稍微小一点,你知道会带来多少的悲哀吗?       跑高速的时候,有时候两辆车轻微碰擦,就会带来几十公里的拥堵....这就是局部事故引发全局连锁反应.前年,沪嘉高速施工,拆除中心绿化带,取消硬路肩,将二车道改为三车道,你可别小看这一根车道,作用大了.       对于网络而言,数据包在网线上的时候,绝对安全,绝对是全速前进,最危险的就是到达转发设备内部,设备处理数据包带来的固有延迟导致数据包必须有机会被缓冲,处理加速比一定要和缓冲区大小对应,

tcp与udp缓冲区大小总结(转载)

1.tcp收发缓冲区默认值 [[email protected] /]# cat /proc/sys/net/ipv4/tcp_rmem 4096    87380   4194304 87380  :tcp接收缓冲区的默认值 [[email protected] /]# cat /proc/sys/net/ipv4/tcp_wmem 4096    16384   4194304 16384  : tcp发送缓冲区的默认值 2.udp收发缓冲区默认值 [[email protected] /]

修改帧大小和socket缓冲区大小(转)

修改帧大小和socket缓冲区大小 MTU (最大传输单元)的缺省值为1500. 通过下面命令将其改为9000(jumbo frame) % ifconfig eth0 mtu 9000 socket buffer size缺省为64 kB. 理论上,最优的buffer大小为<bandwidth>*<round-trip delay> 可以通过下列命令改变其大小(如256KB) % sysctl -w net.core.rmem_max=262144 :最大的接收缓冲区大小(tcp

如何设置 Windows 默认命令行窗口大小和缓冲区大小

关键字: 命令行不能全屏 命令行最大化只有一半屏幕 命令行 字体 背景 颜色 解决方案:http://unmi.cc/save-windows-command-size/ 简要说明: win+r,输入cmd调出命令行窗口,然后在上方右键属性,设置好自己喜好的方案以后,在注册表找 HKEY_CURRENT_USER\Console 是默认的命令行方案,HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe是当前这个命令行的属性,把这些属性的值

Socket编程注意接收缓冲区大小

最近在做一个udp升级程序,因文件有点大,需要将程序分成多个包发送,每次发送一个包,收到回复后发送下一个包,直到完成,这样就控制为顺序发送,保证了完整性,简单定义一个协议,每个包,包含包编号,当前数据长度等信息 包头 命令 子命令 总包数 包编号 总长度 当前包长度 校验信息 数据 6byte 1 1 1 1 4 4 2 0-1024 命令:290 子命令:发送开始为 1   发送数据为2  发送成功为3(接收端发送给发送端)  发送失败为4 总包数: 文件分成多少个包 包编号:当前发送的是第几

[cmd]如何设置 Windows 默认命令行窗口大小和缓冲区大小

Windows 命令行 cmd 窗口系统默认的大小(80*40)对于现在的屏幕配置已经跟不上时代了,我们总是要把它改大些,而且缓冲区大小也想改得大大的.单纯的为当前的 Windows 命令行窗口修改显示大小和缓冲区大小就简单了,右键命令行窗口标题,属性里改屏幕缓冲区和窗口大小就是,系统会为与当前标题相同的命令行窗口记住你的设置,比如 C:\Windows\system32\cmd.exe.但是经常你又会打开不同标题的命令行窗口,如  Tomat,这时候它又是默认的 80*40 的窗口大小,又得改

[知识笔记]Java 基本数据类型的大小、取值范围、默认值

数据类型 大小(字节) 范围 默认值 boolean 1/8(1bit) true/false false byte 1 -128~127 (-2^7~2^7-1) 0 short 2 -32768~32767 (-2^15~2^15-1) 0 char 2 \u0000-\uffff (0-2^16-1) 0 int 4 -2147483648~2147483647 (-2^31~2^31-1) 0 float 4   0.0f long 8 -2^63~2^63-1 0 double 8  

传输层(3)-缓冲区大小及限制、TCP输出

3.缓冲区大小及限制 影响IP数据报大小的限制. 1)IPv4数据报,最大大小是65535. 2)硬件规定的MTU.以太网的MTU是1500字节.SLIP链路1006字节或296字节 3)路径MTU.两个主机之间路径中最小的MTU.1500字节常见的路径MTU 4)IP数据报>MTU,IPv4执行分片 5)IPv4,DF位被设置(不分片).路由器接收到一个超过其外出链路MTU大小且设置了DF位的IPv4数据报时,它将产生一个ICMPv4"destination unreachable, f