关于TCP缓冲区调整的编程讨论

关于TCP缓冲区调整的编程讨论

 
在大容量高性能的电信级系统中,常常使用C/C++语言编写后台服务模块。经常使用的模式是设置TCP为未阻塞模式,然后通过select方式等待socket可读可写再进行网络包读写操作,比如:
 
//wait socket readable or writable
...
select(liSocket+1, ...)
 
//recv tcp buffer
recv(liSocket, ...)
 
此处,我们准备讨论的是TCP的缓冲区问题。系统为每个连接的套接口socket提供发送和接收的缓冲区,系统默认的发送和接收缓冲区大小可以通过以下命令查看:
 
Solaris: /usr/sbin/ndd -get /dev/tcp tcp_recv_hiwat
 
在netstat命令中,我们也可以查看进程的发送和接收缓冲区大小,其最大值与系统默认值相近或相等:
 
netstat -f inet
TCP: IPv4
    Local Address              Remote Address      Swind Send-Q Rwind Recv-Q  State
-------------------- -------------------- ----- ------ ----- ------ -------
localhost.32777          localhost.14141          32768          0 32768          0 ESTABLISHED
localhost.14141          localhost.32777          32768          0 32768          0 ESTABLISHED
localhost.32778          localhost.14141          32768          0 32768          0 ESTABLISHED
localhost.14141          localhost.32778          32768          0 32768          0 ESTABLISHED
 
这里的Swind/Rwind就是表示缓冲区大小,其中Rwind表示进程当前的接收缓冲区大小,同时这个值会在TCP Ack响应中通告网络对端,网络对端根据这个大小来发送信息,如果发送信息大小超过对端的Rwind,则上述的select语句会阻塞,或立刻返回错误。
 
在大容量系统中,当后台进程处理繁忙或者网络负载过大时,经常会发现Rwind变的很小,或者为0,因此我们有时候需要调整其大小,调整的方式包括编码方式和修改系统默认值方式:
 
1)系统修改方式:
 
Solaris: /usr/sbin/ndd -set /dev/tcp tcp_xmit_hiwat 32768
 
2)编码方式:
 
在bind和listen之前,设定参数值:
...
int liValue = 32768;
setsockopt(liListenSocket, SOL_SOCKET, SO_RCVBUF, (char *) &liValue , sizeof(int));
...
 
通过修改这个缓冲区大小,可以适当提高进程的处理能力和容错能力。

你可能感兴趣的:(职场,休闲,TCP缓冲区调整)