免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 13500 | 回复: 8
打印 上一主题 下一主题

[网络子系统] 关于修改Linux协议栈默认的最大缓冲区问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-10-29 15:09 |只看该作者 |倒序浏览
各位大侠:
  工作中我碰到一个如下问题:
  1:Linux内核版本完全相同 为2.6.2版本 在A嵌入式设备上 ,通过查看/proc/sys/net/core/rmem_max,在B嵌入式设备上UDP最大缓冲区是32767字节,我想把它调大为65535
    请问各位大侠 /proc/sys/net/core/rmem_max Linux默认的UDP缓冲区大小修改之后,除了对内存产生影响外,其它还有什   么影响吗?   
  盼回复!

论坛徽章:
0
2 [报告]
发表于 2012-10-29 16:37 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
3 [报告]
发表于 2012-10-29 18:21 |只看该作者
hello,
   多谢你的回复,我有点疑问:
1:协议栈在调用setsockopt时与rmem_max进行比较的,rmem_max默认值与内核版本有关,2.6.2是65535,在协议栈初始化时会计算内存大小,小于16M设置为65535.这个应该是缓冲区的大小,而不是一次要接收的大小。
2:我还碰到一个问题,在Linux上(内核版本2.6.2)与windows XP上做了如下对比:
1):创建一个UDP套接字,发送缓冲区和接收缓冲区都设置为32K
2):Linux发送32K数据(用户数据),windows可以接收到32K,但是windows发32K数据,Linux接收不到,
  只有在发小于等于27K,Linux才可以接收到,测试数据如下:
我的疑问时,调用setsockopt设置的接收缓冲区不是用户可用的缓冲区吗?为什么Linux放不下那么大的数据呢?
Linux是不是又做过什么特殊处理?
欢迎指教哦:wink:

论坛徽章:
0
4 [报告]
发表于 2012-10-29 20:34 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
5 [报告]
发表于 2012-10-30 07:48 |只看该作者
回复 1# zyl1005
 /proc/sys/net/core/rmem_max 的含义是指内核最多为一个socket缓存多少数据。
比如你echo "65535" >  /proc/sys/net/core/rmem_max
减少A程序read这个socket,B程序从另一台服务器发送数据包,如果A的处理速度非常慢,B的发送速度非常快,当内核socket缓存超过65535字节后,B发送的数据包就会被A的内核丢弃。

   

论坛徽章:
0
6 [报告]
发表于 2012-10-30 15:37 |只看该作者
hello,
    版主,你好!
   多谢你的回复,我有个疑问,这个/proc/sys/net/core/rmem_max 假设65535,
这个缓存是指的哪个缓存,是用户的还是系统的?
譬如我在Linux上调用setsockopt函数设置的缓冲区为32K,从windows发送32K数据(用户数据Buf),但是Linux接收不到,只有发送少于27K的数据,Linux才能收到,反之,在windows上调用setsockopt函数设置的缓冲区为32K,Linux发送32K数据(用户数据Buf),windows可以接收到。

一般的理解是调用setsockopt函数设置的缓冲区应是用户的缓冲区,但是Linux好像不是,Linux网络包是基于sk_buff的,这个用户可用缓冲区就降低了,不知这样解释正确吗?
  期待你的回复。

论坛徽章:
0
7 [报告]
发表于 2012-10-30 20:23 |只看该作者
http://www.kernel.org/doc/man-pages/online/pages/man7/tcp.7.html
1: Buffer size
       The maximum sizes for socket buffers declared via the SO_SNDBUF and SO_RCVBUF
       mechanisms are limited by the values in the /proc/sys/net/core/rmem_max and
       /proc/sys/net/core/wmem_max
files.  Note that TCP actually allocates twice the
       size of the buffer requested in the setsockopt(2) call, and so a succeeding
       getsockopt(2) call will not return the same size of buffer as requested in the
       setsockopt(2) call.  TCP uses the extra space for administrative purposes and
       internal kernel structures, and the /proc file values reflect the larger sizes
       compared to the actual TCP windows.  On individual connections, the socket
       buffer size must be set prior to the listen(2) or connect(2) calls in order to
       have it take effect.  See socket(7) for more information.
由上文可看出,socket缓存大小不仅取决于setsockopt设置的大小,还受限于/proc/sys/net/core/rmem_max and /proc/sys/net/core/wmem_max
2:  UDP由于BUFFER SIZE引起的丢包问题
      参见《UNIX® Network Programming Volume 1》 中 8.13 Lack of Flow Control with UDP
注意如下描述:
    Why do we set the receive socket buffer size to 220 x 1,024 in Figure 8.22? The maximum size of a socket receive buffer in FreeBSD 5.1 defaults to 262,144 bytes (256 x 1,024), but due to the buffer allocation policy (described in Chapter 2 of TCPv2), the actual limit is 233,016 bytes. Many earlier systems based on 4.3BSD restricted the size of a socket buffer to around 52,000 bytes
    所以可以解答Linux 系统是32K 发送数据也是32K,为什么在27K时可以接收成功,看样子是由于BUFFER里面除了数据还包括一些头结构,导致真正可用数据不到32K.

论坛徽章:
0
8 [报告]
发表于 2012-10-30 22:11 |只看该作者
hello,
版主,你好!
    多谢你的回复,
1:第一个问题
我看了协议栈代码,调用setsockopt时设置缓冲区时,是会与/proc/sys/net/core/wmem_max 比较的,这个我已经理解了。
2:第二个问题
   我看了unix网络编程的中文版,那个缓冲区时因为BSD版本不同有最高限制,通过查找资料,Linux设置的这个缓冲区实际上不是用户可用的缓冲区,
Linux基于sk_buff数据结果进行网络数据收发,每个IP包都会有个sk_buff数据结果而且还包括整个的报文,因此会大大降低实际应用缓冲区,我发现2.6.16内核版本对
/proc/sys/net/core/wmem_max 默认值已经包含了sk_buff的大小,不知我说的对否?
盼回复,多谢!

论坛徽章:
0
9 [报告]
发表于 2012-10-30 22:13 |只看该作者
回复 7# skychgg
hello,
你好!
     多谢你的回复,
1:第一个问题
我看了协议栈代码,调用setsockopt时设置缓冲区时,是会与/proc/sys/net/core/wmem_max 比较的,这个我已经理解了。
2:第二个问题
    我看了unix网络编程的中文版,那个缓冲区时因为BSD版本不同有最高限制,通过查找资料,Linux设置的这个缓冲区实际上不是用户可用的缓冲区,
Linux基于sk_buff数据结果进行网络数据收发,每个IP包都会有个sk_buff数据结果而且还包括整个的报文,因此会大大降低实际应用缓冲区,我发现2.6.16内核版本对
/proc/sys/net/core/wmem_max 默认值已经包含了sk_buff的大小,不知我说的对否?
盼回复,多谢!

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP