参考:https://www.cnblogs.com/onesea/p/13053697.html 写的非常好了
补充:
关于close说明:
1.客户端close
(1)发送缓冲区无数据直接发送FIN,发送缓冲区有数据等发送缓冲区发送完毕再发FIN;
(2)接收缓冲区无数据直接发送FIN,接收缓冲区有数据直接发送RST(对端不会返回ACK);
close完后同时关闭socket读写,客户端连接状态:
WAIT_1:发送FIN,等待服务端ACK(客户端调用close)
WAIT_2:接收ACK,等待服务端FIN
TIME_WAIT:接收FIN,等待固定时间(服务端调用close)(保证服务端可以收到FIN,所以一般不建议服务器主动close,容易产生大量CLOSE_WAIT)
2.服务端接收FIN/RST
(1)接收FIN(说明客户端发送缓冲区和接收缓冲区均没有数据,且服务端发送缓冲区也没数据),此时服务端只能调用recv(若再调用send发送数据,客户端会返回RST)
(2)接收RST,丢弃发送缓冲区数据,关闭socket写通道,保留接收缓冲区数据,可以继续调用recv。
服务端连接状态:
CLOSE_WAIT:接收FIN,回复ACK(客户端调用close)
LAST_ACK:发送FIN,等待ACK(服务端调用close)
CLOSED:接收ACK,连接关闭