Linux下TCP/IP socket 编程二

时间:2021-05-21 10:21:02

TCP状态转换


Linux下TCP/IP socket 编程二

状态解释

TCP一共具有11种状态,上图为各种状态之间的转换,如下为11种状态的详解以及调用哪些函数所产生
1. CLOSED:起始和结束点,代表最初的状态也代表最后的状态
2. LISTEN:服务器端的状态,代表此端口正在监听是否有客户连接 (调用socket,bind函数成功返回)
3. SYN_RCVD:服务器端的状态,代表本端接收到了客户端的SYN分节 (对端调用connect还未成功返回)
4. SYN_SENT:客户端的状态,代表本端发送了第一个SYN分节,等待ACK分节 (本端调用connect还未成功返回)
5. ESTABLISHED:服务器和客户端的状态,代表套接字已成功建立连接 (服务器端accept,客户端connect成功返回)
6. FIN_WAIT_1:主动关闭方的状态,代表本端已发送了FIN分节 (本端调用close函数)
7. FIN_WAIT_2:主动关闭方的状态,代表本端接收到了对端对FIN分节回应的ACK分节 (对端read函数返回0时向本端发送ACK)
8. TIME_WAIT:主动关闭方的状态,代表本端接收到了对端的FIN分节 (对端调用了close函数)
9. CLOSE_WAIT:被动关闭方的状态,代表本端接收到了FIN分节 (对端调用了close函数)
10. LAST_ACK:被动关闭方的状态,代表本端发送了FIN分节 (本端调用了close函数)
11.CLOSEING:服务器和客户端基本同时发送了FIN分节 (两端同时调用close函数)


TIME_WAIT状态代表主动关闭方接收到了被动关闭方发送的FIN分节,并会向被动关闭方发送ACK分节进行确认,此时被动关闭接收到了ACK分节,会由LAST_ACK状态变成CLOSED状态,主动关闭方则需要等待2MSL(最长分节生命周期)才会由TIME_WAIT状态变成CLOSED状态,此状态存在的原因有如下两点:

  1. 可靠的终止TCP全双工连接

    主动关闭方接收到了对方的FIN分节,需要发送一个ACK分节给对方进行确认,如果ACK分节在网络上丢失,长时间没有接收到ACK确认分节的被动关闭方会再次发送FIN分节,如果主动关闭方没有维护状态信息,就会给被动发送方发送一个RST分节,此分节将会被被动关闭方解释为错误,TCP就没有可靠的终止连接,但因为有了TIME_WAIT状态,主动关闭方维护了状态信息,所以会重新给被动关闭方发送一个ACK分节,此时TCP就可靠的终止了套接字连接

  2. 允许老的重复分节在网络中消逝

    TCP允许分节在网络中存活的最长时间为MSL,超过这个时间则被丢弃!假设一个客户端连接上了服务器,通信一段时间断开连接,然后立刻启动另一个客户端使用相同的IP地址和端口去连接服务器,如果前一个客户端还残留着数据在网络中,当新的连接建立时,由于是相同的端口和IP地址,所以服务器收到了前者残留的数据会当作新的连接的数据进行处理,造成数据混乱的现象!而有了TIME_WAIT的2MSL等待,则会让客户端发送个服务器的分节以及服务器回复给客户端的分节都会消逝在网络中,因为系统不允许处于TIME_WAIT状态的端口进行重使用

关于FIN_WAIT_2状态的说明:此状态就是著名的半关闭状态,应用层此时已经无法发送数据,但是可以接收数据(shutdown函数对此状态进行了支持)

连接三次握手 关闭四次握手的原因
close 与shoutdown函数区别:
close适用于所有的类型的描述符,而shutdown是专门为socket套接字准备的,close关闭描述符的时候会考虑引用计数问题
调用了shutdown之后还是调用close来关闭fd的
tcp协议:http://kb.cnblogs.com/page/209100/
浅谈tcp的半关闭状态:http://www.chinaitlab.com/cisco/TCP/940537.html

RST 代表复位,用来异常的关闭连接,