socketc socket 缓冲区设置可以设置多大

温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
分类:& 10:55&2777人阅读&(1)&&主  题: 浅析:setsockopt()改善程序的健壮性&作  者: gdy119 (夜风微凉)&不断的收到coolmei25 (梅生)的答谢,我都不好意思了(我都没帮到他),下面写出我在网络编程中的一点心得体会,希望对他(^_^也对大家)有帮助:1. 如果在已经处于 ESTABLISHED状态下的socket(一般由端口号和标志符区分)调用closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:BOOL bReuseaddr=TRUE;setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL));2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历TIME_WAIT的过程:BOOL bDontLinger = FALSE;&setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const char*)&bDontLinger,sizeof(BOOL));3.在send(),recv()过程中有时由于网络状况等原因,发收不能预期进行,而设置收发时限:int nNetTimeout=1000;//1秒//发送时限setsockopt(socket,SOL_S0CKET,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int));//接收时限setsockopt(socket,SOL_S0CKET,SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int));4.在send()的时候,返回的是实际发送出去的字节(同步)或发送到socket缓冲区的字节(异步);系统默认的状态发送和接收一次为8688字节(约为8.5K);在实际的过程中发送数据和接收数据量比较大,可以设置socket缓冲区,而避免了send(),recv()不断的循环收发:// 接收缓冲区int nRecvBuf=32*1024;//设置为32Ksetsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));//发送缓冲区int nSendBuf=32*1024;//设置为32Ksetsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));5. 如果在发送数据的时,希望不经历由系统缓冲区到socket缓冲区的拷贝而影响程序的性能:int nZero=0;setsockopt(socket,SOL_S0CKET,SO_SNDBUF,(char *)&nZero,sizeof(nZero));6.同上在recv()完成上述功能(默认情况是将socket缓冲区的内容拷贝到系统缓冲区):int nZero=0;setsockopt(socket,SOL_S0CKET,SO_RCVBUF,(char *)&nZero,sizeof(int));7.一般在发送UDP数据报的时候,希望该socket发送的数据具有广播特性:BOOL bBroadcast=TRUE;&setsockopt(s,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadcast,sizeof(BOOL));8.在client连接服务器过程中,如果处于非阻塞模式下的socket在connect()的过程中可以设置connect()延时,直到accpet()被呼叫(本函数设置只有在非阻塞的过程中有显著的作用,在阻塞的函数调用中作用不大)BOOL bConditionalAccept=TRUE;setsockopt(s,SOL_SOCKET,SO_CONDITIONAL_ACCEPT,(const char*)&bConditionalAccept,sizeof(BOOL));9.如果在发送数据的过程中(send()没有完成,还有数据没发送)而调用了closesocket(),以前我们一般采取的措施是"从容关闭"shutdown(s,SD_BOTH),但是数据是肯定丢失了,如何设置让程序满足具体应用的要求(即让没发完的数据发送出去后在关闭socket)?struct linger {u_short l_u_short l_};linger m_sLm_sLinger.l_onoff=1;//(在closesocket()调用,但是还有数据没发送完毕的时候容许逗留)// 如果m_sLinger.l_onoff=0;则功能和2.)作用相同;m_sLinger.l_linger=5;//(容许逗留的时间为5秒)setsockopt(s,SOL_SOCKET,SO_LINGER,(const char*)&m_sLinger,sizeof(linger));Note:1.在设置了逗留延时,用于一个非阻塞的socket是作用不大的,最好不用;2.如果想要程序不经历SO_LINGER需要设置SO_DONTLINGER,或者设置l_onoff=0;10.还一个用的比较少的是在SDI或者是Dialog的程序中,可以记录socket的调试信息:(前不久做过这个函数的测试,调式信息可以保存,包括socket建立时候的参数,采用的具体协议,以及出错的代码都可以记录下来)BOOL bDebug=TRUE;setsockopt(s,SOL_SOCKET,SO_DEBUG,(const char*)&bDebug,sizeof(BOOL));11.附加:往往通过setsockopt()设置了缓冲区大小,但还不能满足数据的传输需求,我的习惯是自己写个处理网络缓冲的类,动态分配内存;下面我将这个类写出,希望对初学者有所帮助://仿照String 改写而成//==============================================================================// 二进制数据,主要用于收发网络缓冲区的数据// CNetIOBuffer 以 MFC 类 CString 的源代码作为蓝本改写而成,用法与 CString 类似,// 但是 CNetIOBuffer 中存放的是纯粹的二进制数据,'/0' 并不作为它的结束标志。// 其数据长度可以通过 GetLength() 获得,缓冲区地址可以通过运算符 LPBYTE 获得。//==============================================================================// Copyright (c) All-Vision Corporation. All rights reserved.// Module: NetObject// File: SimpleIOBuffer.h// Author: gdy119// Email :&// Date: //==============================================================================// NetIOBuffer.h#ifndef _NETIOBUFFER_H#define _NETIOBUFFER_H//=============================================================================#define MAX_BUFFER_LENGTH //=============================================================================//主要用来处理网络缓冲的数据class CNetIOBuffer&{protected:LPBYTE m_pbinDint m_nLint m_nTotalLCRITICAL_SECTIONm_void Initvalibers();public:CNetIOBuffer();CNetIOBuffer(const LPBYTE lbbyte, int nLength);CNetIOBuffer(const CNetIOBuffer&binarySrc);virtual ~CNetIOBuffer();//=============================================================================BOOL CopyData(const LPBYTE lbbyte, int nLength);BOOL ConcatData(const LPBYTE lbbyte, int nLength);void ResetIoBuffer();int GetLength()BOOL SetLength(int nLen);LPBYTE GetCurPos();int GetRemainLen();BOOL IsEmpty()operator LPBYTE()static GetMaxLength() { return MAX_BUFFER_LENGTH; }const CNetIOBuffer& operator=(const CNetIOBuffer& buffSrc);};#endif //&// NetOBuffer.cpp: implementation of the CNetIOBuffer class.//======================================================================#include "stdafx.h"#include "NetIOBuffer.h"//======================================================================//=======================================================================// Construction/DestructionCNetIOBuffer::CNetIOBuffer(){Initvalibers();}CNetIOBuffer::CNetIOBuffer(const LPBYTE lbbyte, int nLength){Initvalibers();CopyData(lbbyte, nLength);}CNetIOBuffer::~CNetIOBuffer(){delete []m_pbinDm_pbinData=NULL;DeleteCriticalSection(&m_cs);}CNetIOBuffer::CNetIOBuffer(const CNetIOBuffer&binarySrc){Initvalibers();CopyData(binarySrc,binarySrc.GetLength());}void CNetIOBuffer::Initvalibers(){m_pbinData = NULL;m_nLength = 0;m_nTotalLength = MAX_BUFFER_LENGTH;if(m_pbinData==NULL){m_pbinData=new BYTE[m_nTotalLength];ASSERT(m_pbinData!=NULL);}InitializeCriticalSection(&m_cs);}void CNetIOBuffer::ResetIoBuffer(){EnterCriticalSection(&m_cs);m_nLength = 0;memset(m_pbinData,0,m_nTotalLength);LeaveCriticalSection(&m_cs);}BOOL CNetIOBuffer::CopyData(const LPBYTE lbbyte, int nLength){if( nLength & MAX_BUFFER_LENGTH )return FALSE;ResetIoBuffer();EnterCriticalSection(&m_cs);memcpy(m_pbinData, lbbyte, nLength );m_nLength = nLLeaveCriticalSection(&m_cs);return TRUE;}BOOL CNetIOBuffer::ConcatData(const LPBYTE lbbyte, int nLength){if( m_nLength + nLength & MAX_BUFFER_LENGTH )return FALSE;EnterCriticalSection(&m_cs);memcpy(m_pbinData+m_nLength, lbbyte, nLength );m_nLength += nLLeaveCriticalSection(&m_cs);return TRUE;}int CNetIOBuffer::GetLength() const{return m_nL}BOOL CNetIOBuffer::SetLength(int nLen){if( nLen & MAX_BUFFER_LENGTH )return FALSE;EnterCriticalSection(&m_cs);m_nLength = nLLeaveCriticalSection(&m_cs);return TRUE;}LPBYTE CNetIOBuffer::GetCurPos(){if( m_nLength & MAX_BUFFER_LENGTH )return (m_pbinData+m_nLength);elsereturn NULL;}CNetIOBuffer:: operator LPBYTE() const{return m_pbinD}int CNetIOBuffer::GetRemainLen(){return MAX_BUFFER_LENGTH - m_nL}BOOL CNetIOBuffer::IsEmpty() const{return m_nLength == 0;}const CNetIOBuffer& CNetIOBuffer:: operator=(const CNetIOBuffer& buffSrc){if(&buffSrc!=this){CopyData(buffSrc, buffSrc.GetLength());}return *}
阅读(5245)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'设置SOCKET的发送与接收缓冲区',
blogAbstract:'&分类:&'
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}帐号:密码:下次自动登录{url:/nForum/slist.json?uid=guest&root=list-section}{url:/nForum/nlist.json?uid=guest&root=list-section}
贴数:9&分页:&发信人: ruiter (男人23), 信区: NetPRG
标&&题: 关于改变socket接收和发送缓冲区大小的问题
发信站: BBS 水木清华站 (Wed Aug 27 16:48:56 2003), 转信 && 我现在想要改变socket发送和接收数据的缓冲区大小来测试一下数据,用的是如下的语句
来进行改变:setsockopt(socket,SOL_SOCKET,SO_RCVBUF,(char *)&opt,sizeof(opt)),
其中opt是要改变的buffer的大小;现在有如下的问题: &&&& 我现在有一个client和一个server,我的client端负责发送而server端负责接受数据
然后对数据不作处理,server和client端都运行在本机上; &&&& 现在我要用client对server发送同样大小的数据时,其socket缓冲区大小不同时发送
时间进行统计比较,具体的做法是,假设发送的数据是5000000,第一种情况下设置client
端的发送socket和server端的接受socket的buffer(也就是上面的opt)都是要大
于发送数据的大小,这种情况应该是正常的情况,我进行一千次的发送,最终用的时间是
20左右。然后进行第二种情况的测试,发送数据的大小不变,但是我把两边的socket的
buffer的大小变成了100000,也就是说这个时候发送的数据要大于socket缓冲区的大小;
我在网上查到的socket的解决办法应该是分多次传送,所以这个时间在理论上应该长一些
,但是实际中却和第一种情况差不多,所以我现在比较迷惑,请大虾指定,是我那一部分
的理解有问题,顺便附上关键部分的代码: &&&&
client端: &&&&&&&& for(i=0;i&1000;i++){ &&&&&&&&&&&&&&&& send(client_sock,sendBuffer,DATASIZE,0); &&&&&&&&&&&&for(i=0;i&1000;i++){ &&&&&&&&&&&&&&&&recv(socket,recvBuffer,DATASIZE,0); &&&&&&&& } &&&&&&&& 其中client段不管DATASIZE多大,都是一次发送完毕,server段也是一次接收
完毕,不知道这样是不是当socket的buffer大小小于DATASIZE的时候会有问题;请大虾
指点。 &&&& -- && ※ 来源:·BBS 水木清华站 smth.org·[FROM: 210.25.133.3]
&pubby发信人: nukq (悦), 信区: NetPRG
标&&题: Re: 关于改变socket接收和发送缓冲区大小的问题
发信站: BBS 水木清华站 (Wed Aug 27 17:19:42 2003), 转信 &&&& 【 在 ruiter (男人23) 的大作中提到: 】
: 标&&题: 关于改变socket接收和发送缓冲区大小的问题
: 发信站: BBS 水木清华站 (Wed Aug 27 16:48:56 2003), 转信
: 我现在想要改变socket发送和接收数据的缓冲区大小来测试一下数据,用的是如下的语句
: 来进行改变:setsockopt(socket,SOL_SOCKET,SO_RCVBUF,(char *)&opt,sizeof(opt)),
: 其中opt是要改变的buffer的大小;现在有如下的问题:
:&&&& 我现在有一个client和一个server,我的client端负责发送而server端负责接受数据
: 然后对数据不作处理,server和client端都运行在本机上;
:&&&& 现在我要用client对server发送同样大小的数据时,其socket缓冲区大小不同时发送
: 时间进行统计比较,具体的做法是,假设发送的数据是5000000,第一种情况下设置client
: 端的发送socket和server端的接受socket的buffer(也就是上面的opt)都是要大
: 于发送数据的大小,这种情况应该是正常的情况,我进行一千次的发送,最终用的时间是
: 20左右。然后进行第二种情况的测试,发送数据的大小不变,但是我把两边的socket的
: buffer的大小变成了100000,也就是说这个时候发送的数据要大于socket缓冲区的大小;
: 我在网上查到的socket的解决办法应该是分多次传送,所以这个时间在理论上应该长一些
: ,但是实际中却和第一种情况差不多,所以我现在比较迷惑,请大虾指定,是我那一部分
: 的理解有问题,顺便附上关键部分的代码:
: client端:
:&&&&&&&& for(i=0;i&1000;i++){
:&&&&&&&&&&&&&&&& send(client_sock,sendBuffer,DATASIZE,0);
:&&&&&&&&for(i=0;i&1000;i++){
:&&&&&&&&&&&&&&&&recv(socket,recvBuffer,DATASIZE,0);
:&&&&&&&& }
:&&&&&&&& 其中client段不管DATASIZE多大,都是一次发送完毕,server段也是一次接收
: 完毕,不知道这样是不是当socket的buffer大小小于DATASIZE的时候会有问题;请大虾
:&& && 光代码就有问题,setsockopt send recv 的返回值都没检查。
: ※ 来源:·BBS 水木清华站 smth.org·[FROM: 210.25.133.3]
&&&&&& ※ 来源:·BBS 水木清华站 smth.org·[FROM: 218.72.15.84]
&发信人: ruiter (男人23), 信区: NetPRG
标&&题: Re: 关于改变socket接收和发送缓冲区大小的问题
发信站: BBS 水木清华站 (Wed Aug 27 17:22:53 2003), 转信 && 你说的问题很对,我写在上面的都是简单的示例,在实际程序中肯定是有返回值的
而且我再追踪的时候每个都是成功的,请帮忙看看实际的问题好吗;而且我在追踪
的时候发现,无论把socket的缓冲区设为多大,send的返回值都是DATASIZE的大小
而recv的返回值也都是DATASIZE的大小。
【 在 nukq (悦) 的大作中提到: 】
:&& 光代码就有问题,setsockopt send recv 的返回值都没检查。
※ 修改:·ruiter 于 Aug 27 17:26:18 修改本文·[FROM:&&&&210.25.133.3]
: ※ 来源:·BBS 水木清华站 smth.org·[FROM: 218.72.15.84]
&&&& -- && ※ 修改:·ruiter 于 Aug 27 17:26:18 修改本文·[FROM:&&&&210.25.133.3]
※ 来源:·BBS 水木清华站 smth.org·[FROM: 210.25.133.3]
&pubby发信人: nukq (悦), 信区: NetPRG
标&&题: Re: 关于改变socket接收和发送缓冲区大小的问题
发信站: BBS 水木清华站 (Wed Aug 27 17:30:57 2003), 转信 &&&& 我在想通过调整bufsize来提速真的会有效果嘛? && 倒是在使用udp的时候可以减少丢包。 && 【 在 ruiter (男人23) 的大作中提到: 】
: 你说的问题很对,我写在上面的都是简单的示例,在实际程序中肯定是有返回值的
: 而且我再追踪的时候每个都是成功的,请帮忙看看实际的问题好吗;而且我在追踪
: 的时候发现,无论把socket的缓冲区设为多大,send的返回值都是DATASIZE的大小
: 而recv的返回值也都是DATASIZE的大小。
: ※ 修改:·ruiter 于 Aug 27 17:26:18 修改本文·[FROM:&&&&210.25.133.3]
&&&&&& ※ 来源:·BBS 水木清华站 smth.org·[FROM: 218.72.15.84]
&发信人: ruiter (男人23), 信区: NetPRG
标&&题: Re: 关于改变socket接收和发送缓冲区大小的问题
发信站: BBS 水木清华站 (Wed Aug 27 17:38:03 2003), 转信 && 我倒没有想的太多,也没有指望它能够提速,我只是想知道,为什么我改变了bufsize
,但是在send数据的时候这个bufsize却不起作用那,是不是我哪里想的不对。
【 在 nukq (悦) 的大作中提到: 】
: 我在想通过调整bufsize来提速真的会有效果嘛?
: 倒是在使用udp的时候可以减少丢包。
: ※ 来源:·BBS 水木清华站 smth.org·[FROM: 218.72.15.84]
&&&& -- && ※ 来源:·BBS 水木清华站 smth.org·[FROM: 210.25.133.3]
&lgh发信人: lgh (猫头鹰), 信区: NetPRG
标&&题: Re: 关于改变socket接收和发送缓冲区大小的问题
发信站: BBS 水木清华站 (Wed Aug 27 17:52:30 2003), 转信 && 本机传本机提高sndbuf没用,瓶颈不在这里。
只有当遇到high delay×bandwidth的链路提高buf才有用。
而且,sndbuf,rcvbuf也是有上限的。 && 【 在 ruiter (男人23) 的大作中提到: 】
: 我现在想要改变socket发送和接收数据的缓冲区大小来测试一下数据,用的是如下的语句
: 来进行改变:setsockopt(socket,SOL_SOCKET,SO_RCVBUF,(char *)&opt,sizeof(opt)),
: 其中opt是要改变的buffer的大小;现在有如下的问题:
:&&&& 我现在有一个client和一个server,我的client端负责发送而server端负责接受数据
: 然后对数据不作处理,server和client端都运行在本机上;
:&&&& 现在我要用client对server发送同样大小的数据时,其socket缓冲区大小不同时发送
: 时间进行统计比较,具体的做法是,假设发送的数据是5000000,第一种情况下设置client
: 端的发送socket和server端的接受socket的buffer(也就是上面的opt)都是要大
: 于发送数据的大小,这种情况应该是正常的情况,我进行一千次的发送,最终用的时间是
: 20左右。然后进行第二种情况的测试,发送数据的大小不变,但是我把两边的socket的
: buffer的大小变成了100000,也就是说这个时候发送的数据要大于socket缓冲区的大小;
: ...................
&& -- && ※ 修改:·lgh 于 Aug 27 17:53:38 修改本文·[FROM:&&210.25.128.102]
※ 来源:·BBS 水木清华站 smth.org·[FROM: 210.25.128.102]
空中的梦想家发信人: chenqj (青色虫子), 信区: NetPRG
标&&题: Re: 关于改变socket接收和发送缓冲区大小的问题
发信站: BBS 水木清华站 (Wed Aug 27 19:22:27 2003), 转信 && 不是提速
是实验,网络实验,呵呵 && 【 在 nukq (悦) 的大作中提到: 】
: 我在想通过调整bufsize来提速真的会有效果嘛?
: 倒是在使用udp的时候可以减少丢包。
: ※ 来源:·BBS 水木清华站 smth.org·[FROM: 218.72.15.84]
&&&&&&&&&&&&&&&& //&&&&&& ||&&&&&&&&&&︵&&&&&&&&&&&&&&&&&&&&||&&&&&&&& ╭o" )&&&& (oo)&&&&&&o" )▔&&&&&& ( )()&& &&o' ) ()0&&&& ╰( )&&&&@-( )-@&&&& ( )&&&&&& (,,)&&&&0&&&&&&( )&& o&&&&o0()&&&&&&&&()0o'&&&&&&()0o.&&&&/\&&&&&&
&&&& ※ 来源:·BBS 水木清华站 smth.org·[FROM: 210.25.133.8]
空中的梦想家发信人: chenqj (青色虫子), 信区: NetPRG
标&&题: Re: 关于改变socket接收和发送缓冲区大小的问题
发信站: BBS 水木清华站 (Wed Aug 27 19:26:31 2003), 转信 && 因为你网速快,rtt小
【 在 ruiter (男人23) 的大作中提到: 】
: 我倒没有想的太多,也没有指望它能够提速,我只是想知道,为什么我改变了bufsize
: ,但是在send数据的时候这个bufsize却不起作用那,是不是我哪里想的不对。
&&&&&&&&&&&&&&&& //&&&&&& ||&&&&&&&&&&︵&&&&&&&&&&&&&&&&&&&&||&&&&&&&& ╭o" )&&&& (oo)&&&&&&o" )▔&&&&&& ( )()&& &&o' ) ()0&&&& ╰( )&&&&@-( )-@&&&& ( )&&&&&& (,,)&&&&0&&&&&&( )&& o&&&&o0()&&&&&&&&()0o'&&&&&&()0o.&&&&/\&&&&&&
&&&& ※ 来源:·BBS 水木清华站 smth.org·[FROM: 210.25.133.8]
&发信人: ruiter (男人23), 信区: NetPRG
标&&题: Re: 关于改变socket接收和发送缓冲区大小的问题
发信站: BBS 水木清华站 (Wed Aug 27 22:23:13 2003), 转信 && 完了,被揭穿了,那我回头找你问,哼哼。 && 【 在 chenqj (青色虫子) 的大作中提到: 】
: 不是提速
: 是实验,网络实验,呵呵
&&&& -- && ※ 来源:·BBS 水木清华站 smth.org·[FROM: 202.95.16.31]
&文章数:9&分页:Linux下tcp 和 udp 套接字收发缓冲区的大小决定规则_Linux教程_Linux公社-Linux系统门户网站
你好,游客
Linux下tcp 和 udp 套接字收发缓冲区的大小决定规则
来源:Linux社区&
作者:qiaoliang
1. tcp 收发缓冲区默认值
[root@ ]# cat /proc/sys/net/ipv4/tcp_rmem&
4096&&& 87380&& 4161536
87380& :tcp接收缓冲区的默认值
[root@ ]# cat /proc/sys/net/ipv4/tcp_wmem
4096&&& 16384&& 4161536
16384& : tcp 发送缓冲区的默认值
2. tcp 或udp收发缓冲区最大值
[root@ ]# cat /proc/sys/net/core/rmem_max
131071:tcp 或 udp 接收缓冲区最大可设置值的一半。
也就是说调用 setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcv_size, &optlen);& 时rcv_size 如果超过 131071,那么
getsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcv_size, &optlen); 去到的值就等于 131071 * 2 = 262142
[root@ ]# cat /proc/sys/net/core/wmem_max&
131071:tcp 或 udp 发送缓冲区最大可设置值得一半。
跟上面同一个道理
3. udp收发缓冲区默认值
[root@ ]# cat /proc/sys/net/core/rmem_default&&
111616:udp接收缓冲区的默认值
[root@ ]# cat /proc/sys/net/core/wmem_default
111616:udp发送缓冲区的默认值
4. tcp 或udp收发缓冲区最小值
tcp 或udp接收缓冲区的最小值为 256 bytes,由内核的宏决定;
tcp 或udp发送缓冲区的最小值为 2048 bytes,由内核的宏决定
相关资讯 & & &
& (10/08/:39)
& (01/14/:55)
& (02月12日)
& (04/04/:37)
& (11/29/:08)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款在刀片2的 cmm02node06---&cmm02node01 两个结点上,将包长固定在2KB, 用-w选项改变socket buffer size大小,用iperf软件测试两个节点之间的tcp传输带宽,观察随着socket buffer size的变化,传输带宽的变化情况:
1. 只改变发送端的
2. 只改变接收端的
3. 同时改变发送端和接收端的socket buffer size.
在不改变发送和接收缓冲区的大小时:
发送端默认的发送缓冲区大小为19.3KB
接收端默认的接收缓冲区大小为85.3 KB
通过-w win 设置缓冲区大小时,若设置成功,缓冲区大小将被设置为(2*win)B 若设置失败,则缓冲区大小不确定。通过不断增大win值,测得,cmm02node01和cmm02node06的缓冲区大小最大为1GB,继续增大win值时,设置的缓冲区大小反而变小了。证明1GB是这两个服务器的发送缓冲区和接收缓冲区的上限。《unix 网络编程卷一:P164》
当 win 为 1KB 时,应将发送缓冲区大小设置为2KB,发现实际上却被设置为2.23KB. &(why?不知道)
1. 只改变发送端的socket buffer size时,接收端的缓冲区大小为85.3KB。
在 发送缓冲区 &1MB 时, 随着发送缓冲区的增加,带宽逐渐缓慢增加;
在发送缓冲区 & 1MB 后,带宽较快的变大。
win 值 为 1GB 时, 发送缓冲区被设置为 2KB, 带宽减小到 219 Mb/s。
  下面描述了某个应用程序写数据到一个TCP套接字中时发生的步骤。《unix 网络编程卷一:P48》
  每个TCP套接字有一个发送缓冲区,我们可以用SO_SNDBUF套接字选项来更改该缓冲区的大小。当某个应用进程调用write时,内核从该应用进程的缓冲区中复制所有数据到所写套接字的发送缓冲区。如果该套接字的发送缓冲区容不下该应用进程的所有数据(或是应用进程的缓冲区大于套接字的发送缓冲区,或是套接字的发送缓冲区中已有其它数据),该应用进程将被投入睡眠。这里假设该应用进程是阻塞的,它是通常的默认设置。内核将不从write系统调用返回,直到应用进程缓冲区中的所有数据都复制到套接字发送缓冲区。因此,从写一个TCP套接字的write调用成功返回仅仅表示我们可以重新使用原来的应用进程缓冲区,并不表明对端的TCP或应用进程已接收到数据。
  这一端的TCP提取套接字发送缓冲区中的数据并把它发送给对端TCP, 其过程基于TCP数据传送的所有规则(TCPv1的第19章和第20章,有待详细阅读)。对端TCP必须确认收到的数据,伴随来自对端的ACK的不断到达,本端TCP至此才能从套接字发送缓冲区中丢弃已确认的数据。TCP必须为已发送的数据保留一个副本,直到它被对端确认为止。
  本端TCP以MSS大小的或更小的块把数据传递给IP, 同时给每个数据块安上一个TCP首部以构成TCP分节,其中MSS或是由对端通告的值,或是536(若对端未发送一个MSS选项)。(536是IPv4最小重组缓冲区字节数576减去IPv4首部字节数20和TCP首部字节数20的结果。)IP给每个TCP分节安上一个IP首部以构成IP数据报,并按照其目的IP地址查找路由表项以确定外出接口,然后把数据报传递给相应的数据链路。 IP可能在把数据报传递给数据链路之前将其分片,不过我们已经谈到MSS选项的目的之一就是试图避免分片,较新的实现还使用了路径MTU发现功能(之前的测试表明,刀片2上支持路径MTU发现功能)。每个数据链路都有一个输出队列,如果该队列已满,那么新到的分组将被丢弃,并沿协议栈向上返回一个错误:从数据链路到IP, 再从IP到TCP。TCP将注意到这个错误,并在以后的某个时刻重传相应的分节。应用程序并不知道这种暂时的情况。
2. 只改变接收端的socket buffer size时, 发送端的缓冲区大小为19.3KB。
随着接收端缓冲区大小的增加,带宽先增加,后降低;在256KB时,达到最大值。在接收缓冲区大于256KB后,带宽的趋势是突然降低,并随后保持在较低水平。
接收缓冲区被TCP用来保存接收到的数据,直到由应用程序来读取。对于TCP来说,套接字接收缓冲区中可用空间的大小限定了TCP通告对端的窗口大小。TCP套接字接收缓冲区不可能溢出,因为不允许对端发出超过本端所通告窗口大小的数据。这就是TCP的流量控制,如果对端无视窗口大小而发出了超过该窗口大小的数据,本端TCP将丢弃它们。
3. 同时改变发送端和接收端的socket buffer size时。
当缓冲区大小 & 1MB 时, 随着缓冲区的增加,带宽缓慢增加,逐渐平稳在一个较低值;
当缓冲区大小 & 1MB 后,随着缓冲区的增加,带宽先大幅度增加后降低并保持在8~9Gb/s。
比较三种情况下的带宽曲线:&
可以从上图得出的结论是,在现有的网络和硬件环境下, 要得到较大的带宽,有3种情况:
1. 只设置接收端缓冲区大小是达不到最大带宽的,但是接收缓冲区为256KB是一个较好的设置值,可以固定接收端为256KB, 继续测试出一组最佳匹配值。
2. 设置较大的发送端和接收端窗口,最佳匹配是[8MB, 8MB], 也可在最佳匹配值左右进行选择。
3. 只设置大的发送端的缓冲区大小,&=16MB, &此时的带宽能达到12~14Gb/s
1. 固定接收端缓冲区为256KB
将接收端的缓冲区大小固定为256KB,改变发送端的缓冲区大小,测试一组带宽值以找到发送端缓冲区最佳匹配值。由于发送端的发送缓冲区大小设置应大于带宽延迟乘积(见《unix 网络编程卷一:P164》),通过ping命令得到cmm02node01与cmm02node06之间的RTT在0.1ms与0.2ms之间,保守估计按照0.2ms计算,对40Gb以太网数据链路,带宽延迟乘积=40Gb/(8bits/Byte)*0.2ms/(1000ms/s)=1MB, 也就是说,在发送缓冲区小于1MB时,两个通信结点之间的管道容量不会被填满,带宽将不会达到期望值。因此,在下面的测试曲线中,发送缓冲区最小设置为1MB, 最大设置为1GB。
由下图可以看出,固定接收端缓冲区大小为256KB时, 得到的最佳匹配值为[256KB,&= 16MB], 此时的带宽能达到12Gb/s左右。
2. 固定接收端缓冲区大小为8MB
为了验证第二组最佳匹配值,将接收端的缓冲区大小设置为8MB, 发送端缓冲区大小区间为 [1MB, 1GB] , 进行了一组测试。测试结果如下: 从图中可以看出第二组最佳匹配值为[8MB, &=8MB], 此时的带宽能达到12Gb/s左右。
综上所述:
在寻找ROS的socket 缓冲区的最佳匹配值时,有三种匹配值可供选择:
1. 只设置发送缓冲区 &= 16MB
2.&[256KB,&= 16MB]
3.&[8MB, &=8MB]
结论就是,发送缓冲区必须要大, 接收缓冲区在 默认85.3,256KB左右 ,8MB 及以上这三个区间择优选择,最大的带宽应该在12Gb/s左右。
Views(...) Comments()

我要回帖

更多关于 c socket 缓冲区设置 的文章

 

随机推荐