1.TIME_WAIT的原因及解决方式
TIME_WAIT状态,表示端口被占用。处于连接发起方在进行tcp四次挥手过程中发送ACK报文后处于2msl的等待时间,此时,发起方已收到被动关闭方发来的FIN和ack报文,发起方处于TIME_WAIT是确保对方正确接收到ack,让对方自然关闭,也是为了预防一些迷失报文到来产生影响;
措施:tcp_tw_reuse,TIMEW_WAIT创建后1秒,连接方才可以复用此端口的新连接。内核操作,减低timewait时间。避免出现大量的timewait占用系统资源。
2.关闭连接函数close和shutdown
tcp是双向的,分为客户端到服务器,服务器到客户端;当需要只关闭一侧连接时,需要shutdown;
close和shutdown的区别:
1)close,有套接字引用计数变量,当一个进程停止连接时,引用计数减1,当引用计数为0,关闭双侧连接;客户端close后,当服务器发送报文1,会收到RST报文,再次发送报文2,直接触发SIGPIPE信号,服务器连接退出。
2)shutdown客户端调用shutdown后,只关闭连接的一个方向,服务器还可以进行数据的发送和接收。当客户端和服务器端读到eof后,双方正常退出。
3.tcp连接的有效性检测
当tcp连接因为服务器重置等原因失效时,客户端无法及时感应。解决措施:TCP心跳检测:在应用程序简历检测机制,设置保活时间,保活时间内没收到对当前连接的反馈,发起PING操作,只有是PONG的回应才会认为当前连接有效,并重置探活计数器和探活时间。
4.发送窗口,接收窗口,拥塞窗口;
如何有效利用网络带宽?
1)接收端在接收缓冲区空闲达到合理值之后再通知发送端;
2)发送端:Nagle限制大批量的小数据包同时发送;
3)接收端:延时ACK,累计ACK报文到有数据发送时一起发送;
对于Nagle和延时ACK的冲突,可以通过在缓冲区合并数据凑成完整请求来缓解;
5.服务器重启后,再次连接同一个地址和端口,出现此地址已被占用address already in use。
在所有的tcp服务器程序中,调用bind前设置SO_REUSEADDR套接字,表示当tcp连接处于TIME_WAIT时,可以重用端口。
端口复用:方便一个主机有多个地址的情况下,连接同一个端口。
6.一般情况下,send操作只是把数据写入内核缓冲区,如何发送,何时发送由内核协议栈决定。这也意味着tcp连接建立后,对tcp链路的异常感知是有限的,一般有两种情况: