这是我在书上拍的图大家凑合看,图虽不漂亮但是内容好啊
服务器调用socket,bind,listen,后处于LISTEN状态(桢听来自远方TCP端口的连接请求)。称之为被动打开。
客户端通过调用connect激发三路握手,调用connect后处于SYN_SENT状态(在发送连接请求后等待匹配的连接请求)。这将导致TCP发送一个SYN分节,他告诉服务器将在待建立的连接中发送的数据的初始序列号。通常SYN并不携带数据,其所在的IP数据报只包含一个IP首部、一个TCP首部、及可能有的TCP选项。在这个SYN发送到服务器之前accept函数阻塞
服务器必须确认客户的SYN,同时自己发送一个SYN分节,它含有服务器将在同一连接中发送的数据的初始序列号,服务器在单个分节中发送SYN和对客户SYN的ACK.此时服务器处于SYN_RCVD(在接受和发送一个连接请求后等待对方连接请求的确认)
客户端确认服务器的syn。此时客户处于estabished状态(代表一个打开的连接)此时客户的connect函数返回了。
服务器收到来自客户的ACK处于ESTABISHED状态,此时accept函数返回、
此时,连接已经建立,客户构造一个请求发送给服务器。服务器对客户请求的确认是伴随其应答发送的。这种做法成为捎带,他通常在服务器处理请求并产生应答的时间少于200ms时发生,如果服务器耗用更长的时间比如1s,则我们将看到先是确认后是应答。
某个应用进程首先调用close,我们称为主动关闭,该端的TCP于是发送一个FIN分节,表示数据发送完毕。调用后处于FIN_WAIT1状态(等待远程TCP连接中断请求或者先前的TCP连接中断请求)
接受到这个FIN的对端执行被动关闭,处于CLOSE_WAIT状态(等待从本地用户发来的连接中断请求)并发送一个FIN的ACK。FIN作为一个文件结束符传递给应用进程(放在已排队等候该应用进程接受的任何其他数据之后),因为FIN的接受意味着相应连接上再无数据可以接受。
原端接受到这个ACK处于FIN_WAIT2状态,从远程TCP等待连接中断请求。
一段时间后,接收到这个文件结束符的应用程序将调用close关闭他的套接字,这导致他的TCP也发送一个FIN。
原端接受到这个FIN后处于TIME_WAIT状态(等待足够的时间以确保远程TCP接受到连接中断的请求的确认)
对端接受到这个ACK处于closed状态(没有任何连接状态)