客户端死活连不上服务器,原因竟然是time_wait,怎样消除大量的time_wait状态

最近项目中客户端连接服务器时死活都连不上了,服务器查询出现大量time_wait状态,于是迫在眉睫解决问题的着手点是如何避免出现大量的tima_wait状态。下面我将为大家介绍解决的方法:

下面让我们先来了温习下tcp的三次握手和四次挥手的过程图

tcp三次握手

tcp四次挥手

 

在TIME_WAIT状态中,如果TCP client端最后一次发送的ACK丢失了,它将重新发送。TIME_WAIT状态中所需要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待之后连接正式关闭,并且所有的资源(包括端口号)都被释放。

1、断网关闭时先调用shutdown函数

close与shutdown的区别主要表现在:
    close函数会关闭套接字ID,如果有其他的进程共享着这个套接字,那么它仍然是打开的,这个连接仍然可以用来读和写,并且有时候这是非常重要的 ,特别是对于多进程并发服务器来说。

    而shutdown会切断进程共享的套接字的所有连接,不管这个套接字的引用计数是否为零,那些试图读得进程将会接收到EOF标识,那些试图写的进程将会检测到SIGPIPE信号,同时可利用shutdown的第二个参数选择断连的方式。

2、SO_REUSEPORT的使用

SO_REUSEPORT支持多个进程或者线程绑定到同一端口,提高服务器程序的性能,解决的问题:

  • 允许多个套接字 bind()/listen() 同一个TCP/UDP端口   
  •     1)每一个线程拥有自己的服务器套接字
  •     2)在服务器套接字上没有了锁的竞争
  • 内核层面实现负载均衡
  •    1)安全层面,监听同一个端口的套接字只能位于同一个用户下面
int opt_val = 1; 
if(setsockopt(mSockFD, SOL_SOCKET, SO_REUSEPORT, &opt_val, sizeof(opt_val)))
{ 
    cout << "set reuseport error: " << errno << endl; return -errno; 
}

3、setsockopt 设置 SO_LINGER 选项

struct linger so_linger;
so_linger.l_onoff = 1;
so_linger.l_linger = 0;
setsockopt(s,
    SOL_SOCKET,
    SO_LINGER,
    &so_linger,
    sizeof so_linger);

4、设置一些超时参数

设置以下参数
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值