tcp 长链接与短链接

长链接与短链接

  • 使用TCP协议时,会在客户端和服务器之间创建一条虚拟的信道,这条虚拟信道就是指链接,而建议这条链接须要3次握手,拆毁这条链接须要4次挥手,可见,咱们创建这条链接是有成本的,这个成本就是效率成本,简单点说就是时间成本,你要想发送一段数据,必须先3次握手(来往3个包),而后才能发送数据,发送完了,你须要4次挥手(来往4个包)来断开这个链接。
  • 其二,CPU资源成本,三次握手和4次挥手和发送数据都是从网卡里发送出去和接收的,还有其他的设备,好比防火墙,路由器等等,站在操做系统内核的角度来说,若是咱们是一个高并发系统的话,若是大量的数据包都经历过这么一个过程,那是很耗CPU的。
  • 其三,每一个socket是须要耗费系统缓存的,好比系统提供了一些接口设置socket缓存的,好比:
/proc/sys/net/ipv4/tcp_rmem
/proc/sys/net/ipv4/tcp_wmem
/proc/sys/net/ipv4/tcp_mem

keepalive机制

TCP链接一旦创建后,是否是这个链接能够一直保持? 答案是否认的,操做系统在实现TCP协议的时候都作了一个限制,这个限制能够参考配置:缓存

cat /proc/sys/net/ipv4/tcp_keepalive_time
cat /proc/sys/net/ipv4/tcp_keepalive_intvl
cat /proc/sys/net/ipv4/tcp_keepalive_probes
  • 咱们看到默认这个tcp_keepalive_time的值为7200s,也就是2个小时,这个值表明若是TCP链接发送完最后一个ACK包后,若是超过2个小时,没有数据往来,那么这个链接会断掉。那么咱们如何才能保持住这个链接呢?实际上,这就是TCP的keepalive机制,哦,说法不严谨,TCP协议并无规定如此,可是不少的操做系统内核实现TCP协议时,都加上了这个keepalive机制,那么这个功能默认是关闭的,那这个keepalive机制究竟是如何的呢?也就是,若是TCP之间没有任何数据来往了在tcp_keepalive_time(7200s,2h)后,服务器给客户端发送一个探测包,若是对方有回应,说明这个链接还存活,不然继续每隔tcp_keepalive_intvl(默认为75s)给对方发送探测包,若是连续tcp_keepalive_probes(默认为9)次后,依然没有收到对端的回复,那么则认为这个链接已经关闭。
  • tcp keepalive默认不是开启的,若是想使用KeepAlive,须要在你的应用中设置SO_KEEPALIVE才能够生效。固然事先咱们能够修改这些默认值,方法以下:

在Linux中咱们能够经过修改 /etc/sysctl.conf 的全局配置:服务器

net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl=75
net.ipv4.tcp_keepalive_probes=9

添加上面的配置后输入 sysctl -p 使其生效,你可使用 sysctl -a | grep keepalive 命令来查看当前的默认配置并发

tcp keepalive能够经过设置TCP选项设置,设置方法以下:socket

#include <sys/socket.h>

int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len);

咱们在须要使能Keepalive的socket上面调用setsockopt函数即可以打开该socket上面的keepalive。tcp

第一个参数是要设置的套接字 第二个参数是SOL_SOCKET 第三个参数必须是SO_KEEPALIVE 第四个参数必须是一个布尔整型值,0表示关闭,1表示打开 最后一个参数是第四个参数值的大小。函数

示例:高并发

int keepalive = 1;
 setsockopt(incomingsock,SOL_SOCKET,SO_KEEPALIVE,(void*)(&keepalive),(socklen_t)sizeof(keepalive));
                         
 int keepalive_time = 30;
 setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPIDLE,(void*)(&keepalive_time),(socklen_t)sizeof(keepalive_time));
 int keepalive_intvl = 3;
 setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPINTVL,(void*)(&keepalive_intvl),(socklen_t)sizeof(keepalive_intvl));
int keepalive_probes= 3;
 setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPCNT,(void*)(&keepalive_probes),(socklen_t)sizeof(keepalive_probes));

设置SO_KEEPALIVE选项来开启KEEPALIVE,而后经过TCP_KEEPIDLE、TCP_KEEPINTVL和TCP_KEEPCNT设置keepalive的保活时间、间隔、次数等参数。操作系统

相关文章
相关标签/搜索