TCP三次握手和四次挥手

三次握手:

通常建立TCP连接过程如下:

(1) 服务器通过调用socket, bind, listen来等待客户端的连接, 这称为被动连接

(2) 客户端通过调用connect 来发起主动连接, 此时, 客户向服务器发送一个SYN(同步)分节, 他告诉服务器客户将在(即将建立的)连接中发送的数据的初始序列号(这个初始序列号不一定是0, 可以是任何数字), 通常SYN分节不携带数据, 其所在的IP数据包只包含IP首部, TCP首部, 以及可能的TCP选项, 这就是所谓的第一次握手

(3) 服务器接收到客户端发送的SYN以后, 需要做两件事来给客户端反馈: ① 告诉客户端已经收到了他的请求, 并且听明白了他的请求, 即所谓的确认(ACK), 他的值是前一次握手客户端发来的SYN序列号+1② 告诉客户端接下来的通讯中自己发送的数据的初始序列号(SYN, 这个值与收到的SYN无关)。这就是所谓的第二次握手

(4) 客户端收到服务端给的反馈以后, 需要告诉服务端收到了对方的反馈并且明白了对方接下来怎么跟自己沟通, 即向服务端确认(ACK, 他的值同样是上次握手后服务端发来的SYN值+1), 这就是第三次握手。完成此次握手以后连接就已经建立了, 事实上, 此时已经可以携带数据了。

这里需要说明的是, 在完成第二次握手时, 其实从客户端(主动连接方)的角度看, 连接其实建立了, 可以想象两个人打电话, A向B打, B接了, 此时对于A来说, 知道自己可以说正事儿了, 此时主动方的状态变成了所谓的ESTABLISHED, 所以在第三次握手时主动端是可以带上数据的, 但是在第三次握手前从被动连接端的角度来看, 连接还没有建立, 毕竟B可不知道A说的哪国语言, 想说啥, 所以第三次握手是必要的, 通过第三次握手, 被动端知道了双方的确可以无障碍沟通, 在完成第三次握手以后, 被动端的状态转变成ESTABLISHED, 表示连接建立完成。现在我们知道了, 第三次握手时为什么可以带数据(因为大多数情况下不出意外的话, 连接可以建立成功), 也知道了第三次握手的必要性(因为第三次握手是告诉被动端沟通没有障碍, 不然万一被动端不明白主动端说啥呢?)

四次挥手:

关闭TCP连接的过程如下:

(1) 想要关闭的一方首先调用close(), 我们称这端执行主动关闭, 此时这端向对端发送一个FIN分节, 表示数据发送完毕, 这就是所谓的第一次挥手

(2) 接收到上一步返送的FIN分节的端执行被动关闭, 向主动关闭方进行确认(ACK, 值为收到的FIN + 1), 这是第二次挥手。被动关闭端接收到FIN后, 将其作为一个文件结束符, 放在已排队等候应用进程接收的任何其他数据之后, 因为接收到FIN表示不在能接收到其他数据了

(3) 但是在完成第二次挥手后被动关闭方还不能直接关闭连接(当然主动关闭方也不能), 因为此时被动关闭方可能还没接收完数据, 所以需要等待一段时间, 在这之后他才会调用close关闭自己的套接字, 并发送自己的FIN(这个值与收到的FIN无关)给主动连接方, 表示自己已经接收完成所有数据, 可以真正断开连接了, 这是第三次挥手

(4) 主动关闭方接收到被动关闭方发来的FIN, 知道了对方完成了所有数据的接收, 这时候自己才总算可以放心大胆的关闭自己的套接字了, 那么向被动方发送一个确认(ACK, 值是上一步收到的FIN + 1), 然后就可以关闭连接了, 这是第四次挥手

这里需要注意的是, 第一次挥手时, FIN其实可以跟最后发送的数据一起发送, 毕竟这之后真的已经没数据可发了嘛, 而第二, 三次挥手其实也可以合并到一次里, 毕竟如果被动方确定已经接收完数据了何必还要等一段时间呢。

 

posted @ 2018-11-02 18:46  不想取名字所以就随便写了  阅读(137)  评论(0编辑  收藏  举报