公司网站建设方案书怎么写,lnmp wordpress 树莓派,网络推广团队需要哪些人手,wordpress 无刷新分页linux网络编程#xff08;二#xff09;TCP通讯状态TCP状态转换为什么需要等待2MSL#xff1f;端口复用TCP状态转换 tcp协议连接开始会经过三次握手#xff0c;客户端和服务器开始都会处于CLOSED状态 第一次握手#xff1a;客户端会先发送SYN请求给服务器#xff0c;客户…
linux网络编程二TCP通讯状态TCP状态转换为什么需要等待2MSL端口复用TCP状态转换 tcp协议连接开始会经过三次握手客户端和服务器开始都会处于CLOSED状态 第一次握手客户端会先发送SYN请求给服务器客户端处于SYN_SET状态 第二次握手服务器接收到SYN后发给客户端ACK回答和SYN请求服务器从LISTEN变成SYN_RCVD 第三次握手客户端接收到ACK和SYN请求后发送给服务器ACK回应客户端从SYN_SET变成ESTABLISHED状态服务器接收到ACK回应后也变为ESTABLISHED状态
tcp协议关闭会经过四次握手假设客户端为主动关闭服务器为被动关闭 第一次握手客户端发送FIN请求状态变为FIN_WAIT_1 第二次握手服务器接收到FIN请求同时发送ACK应答状态为CLOSE_WAIT,客户端收到ACK应答后变为FIN_WAIT_2状态此时处于半关闭的状态 第三次握手服务器发送FIN请求状态为LACK_ACK 第四次握手客户端接收到FIN请求后发送ACK应答状态变为TIME_WAIT等待2MSL之后关闭
CLOSED表示初始状态。LISTEN该状态表示服务器端的某个SOCKET处于监听状态可以接受连接。SYN_SENT这个状态与SYN_RCVD遥相呼应当客户端SOCKET执行CONNECT连接时它首先发送SYN报文随即进入到了SYN_SENT状态并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。SYN_RCVD: 该状态表示接收到SYN报文在正常情况下这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态很短暂。此种状态时当收到客户端的ACK报文后会进入到ESTABLISHED状态。ESTABLISHED表示连接已经建立。FIN_WAIT_1: FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。区别是FIN_WAIT_1状态是当socket在ESTABLISHED状态时想主动关闭连接向对方发送了FIN报文此时该socket进入到FIN_WAIT_1状态。 FIN_WAIT_2状态是当对方回应ACK后该socket进入到FIN_WAIT_2状态正常情况下对方应马上回应ACK报文所以FIN_WAIT_1状态一般较难见到而FIN_WAIT_2状态可用netstat看到。FIN_WAIT_2主动关闭链接的一方发出FIN收到ACK以后进入该状态。称之为半连接或半关闭状态。该状态下的socket只能接收数据不能发。TIME_WAIT: 表示收到了对方的FIN报文并发送出了ACK报文等2MSL后即可回到CLOSED可用状态。如果FIN_WAIT_1状态下收到对方同时带 FIN标志和ACK标志的报文时可以直接进入到TIME_WAIT状态而无须经过FIN_WAIT_2状态。CLOSING: 这种状态较特殊属于一种较罕见的状态。正常情况下当你发送FIN报文后按理来说是应该先收到或同时收到对方的 ACK报文再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后并没有收到对方的ACK报文反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢如果双方几乎在同时close一个SOCKET的话那么就出现了双方同时发送FIN报文的情况也即会出现CLOSING状态表示双方都正在关闭SOCKET连接。CLOSE_WAIT: 此种状态表示在等待关闭。当对方关闭一个SOCKET后发送FIN报文给自己系统会回应一个ACK报文给对方此时则进入到CLOSE_WAIT状态。接下来呢察看是否还有数据发送给对方如果没有可以close这个SOCKET发送FIN报文给对方即关闭连接。所以在CLOSE_WAIT状态下需要关闭连接。LAST_ACK: 该状态是被动关闭一方在发送FIN报文后最后等待对方的ACK报文。当收到ACK报文后即可以进入到CLOSED可用状态。
为什么需要等待2MSL
当客户端也就是主动关闭的一端接收到服务器也就是被动关闭的一端的FIN请求时需要回应ACK回应但是客户端并不能保证ACK回应服务器一定能收到就添加了一个保护机制在2MSL时间内如果服务器没有收到ACK回应服务器会再一次发送FIN请求知道能收到客户端收到ACK回应。服务器在2MSL之内一直没有收到的话客户端将做超时处理关闭失败。 作用
让4次握手关闭流程更加可靠4次握手的最后一个ACK是是由主动关闭方发送出去的若这个ACK丢失被动关闭方会再次发一个FIN过来。若主动关闭方能够保持一个2MSL的TIME_WAIT状态则有更大的机会让丢失的ACK被再次发送出去。防止lost duplicate对后续新建正常链接的传输造成破坏。lost uplicate在实际的网络中非常常见经常是由于路由器产生故障路径无法收敛导致一个packet在路由器ABC之间做类似死循环的跳转。IP头部有个TTL限制了一个包在网络中的最大跳数因此这个包有两种命运要么最后TTL变为0在网络中消失要么TTL在变为0之前路由器路径收敛它凭借剩余的TTL跳数终于到达目的地。但非常可惜的是TCP通过超时重传机制在早些时候发送了一个跟它一模一样的包并先于它达到了目的地因此它的命运也就注定被TCP协议栈抛弃。
端口复用
在server的TCP连接没有完全断开之前不允许重新监听是不合理的 在server代码的socket()和bind()调用之间插入如下代码
int opt 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, opt, sizeof(opt));