接下来学习的内容涉及:TCP 11种状态,连接建立的三次握手、连接终止的四次握手,TIME_WAIT与SO_REUSEADDR,SIGPIPE等内容。
1.TCP 11种状态
- 连接建立:
(1)B端为服务端,当调用listen之后,就处于监听状态(LISTEN)——此时该套接口称为被动套接口(表示该套接口只能用来接收连接,不能用来发起连接)。
(2)A端为客户端,当调用connect主动打开,该套接口为主动套接口,可以用来发起连接。此时为SYN_SENT状态。(connect阻塞)
(3)客户端发起连接之后,服务器端调用accept,处于SYN_RCVD状态。随后服务端进行确认。(accept阻塞)
(4)客户端收到服务端发送的确认段之后,就处于ESTABLISHED状态。(connect返回)
(5)客服端发送确认段并且服务端收到确认段之后,服务器端处于ESTABLISHED状态。(accept返回)
- 连接终止:
双方都可以主动关闭,假定客户端先关闭
(1)客户端调用close请求关闭,会发送一个FIN的TCP段给对方,此时客户端处于FIN_WAIT_1状态。
(2)服务端收到终止的TCP段之后,会导致read返回为0,并且服务端会对此请求进行确认。此时服务器端处于CLOSE_WAIT状态,客户端处于FIN_WAIT_2状态。
(3)然后服务器端调用close发起一个连接终止的TCP段给对方。这个时候就处于等待对方确认的最后一个状态——LAST_ACK。
(4)客户端收到之后,再发送一个确认段给对方,此时,客户端由FIN_WAIT_2状态转为TIME_WAIT状态。
(5)最后,服务器端收到确认段之后,就变为了CLOSED状态。
- 仔细观察会发现图中只列出了10种状态,其实还有一种状态叫——CLOSING。产生的原因是双方同时关闭。
2.SIGPIPE
(1)往一个已经接收FIN的套接字中写是允许的,接收到FIN仅仅代表对方不再发送数据。
(2)在收到RST段之后,如果在调用write就会产生SIGPIPE信号,对于这个信号的处理我们通常忽略即可:
signal(SIGPIPE, SIG_IGN);