TCP三次握手四次挥手

三次握手(建立连接)

三次握手其实就和我们日常打电话的时候信号不好的时候两个人通过相互 交流确认对方和你之间的连接是稳定的,举个例子:
A:喂,你能听到我的声音吗?
B:我能听到你说,你能听到我说话吗?
A:可以听到。
然后就可以正常的聊天了。
对应的客户端和服务器之间的通信连接如图:
在这里插入图片描述
TCP,名为传输控制协议,是一种可靠的传输层协议,IP协议号为6。
客户端和服务器之间发送的SYN,ACK分别是TCP报文中的标志位。

TCP报文格式图

TCP报文格式图

  • 源/目的端口:表示数据是从哪个进程来,到摩纳哥进程去。
  • 序号:Seq序号,占32位,用来标识从Tcp源端向目的端发送的字节流,发起方发送数据时对此进行标记。
  • 确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
  • 4位的Tcp报头长度:表示该TCp头部有多少个32位的bit(有多少个4字节);所以TCP头部最大长度是15*4=60
  • 6位标志位:
    1. URG:紧急指针是否有效
    2. ACK:确认号是否有效
    3. PSH:提示接受应用程序立刻从TCP缓冲区把数据取走
    4. RST:对方要求重新建立连接;我们把携带RET标识的称为复位报文段
    5. SYN:请求连接;我们把携带SYN标识的称为同步报文段
    6. FIN:通知对方,对端要关闭了,我们携带FIN标识的为结束报文段
  • 16位校验和: 发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含TCP首部, 也
    包含TCP数据部分.
  • 16位紧急指针: 标识哪部分数据是紧急数据;

确认序号Ack和标识位ACK不是能搞混,确认方(服务器)Ack等于发方(客户端)Req+1,两端对齐

三次握手(建立连接)

TCP(Transmission Control Protocol) 传输控制协议
TCP是主机对主机层的传输协议,提供可靠的连接服务,采用三次握手建立连接。三次握手,即建立一个TCP连接,是指建立一个TCP连接时,需要客户端和服务端总共发送三个包以确认间接的建立。具体流程如图:
三次握手图解

  • 第一次握手:客户端将标志位SYN置为1,随机产生一个值撒起就,并将该数据包发送给服务器,客户端进入SYN_SENT状态,等待服务端确认。
  • 第二次握手:服务器收到数据包后由标志位SYN=1知道客户端请求连接,服务器将标志位SYN和ACK都置为1,ack(number)=j+1,随机善生一个值seq=K,并将该数据包发送给客户端以确认连接请求,服务器进入SYN_RCVD状态。
  • 第三次握手:客户端收到确认之后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器,服务器检查ack是否为K+,ACK是否为1,如果正确则连接建立成功,服务器和客户端进入ESTABLSIHED状态

三次握手完成,服务器和客户端之间可以开始传输数据了。在这三次握手的过程中服务器和客户端的状态是不停变换的:

第三次握手的ACK可能也会发生丢包的可能,如果丢包了,服务器将没有进入ESTABLISHED状态,在客户端给服务器发生数据的时候,发生服务器没有进入ESTABLISHED状态,此时客户端会重新请求建立连接,重复三次握手。

客户端状态变化:

  • CLOSE->SYN_SENT:客户端调用con’nect,发送同步报文段。
  • SYN_SENT->ESTABLSHED: connect调用成功,则进入ESTABLISHED状态,开始读入数据。

服务器状态变化

  • CLOSE->LISTEN :服务器调用listent后进入LISTENT状态,等待客户端连接。
  • LISTEN->SYN_RCVD: 一旦监听到连接请求(同步报文段),就将该连接放入内核等待队列中,并向客户端发送SYN确认报文。
  • SYN_REVD->ESTABLISHED: 服务端一旦收到客户端的确认端的确认报文,就会进入ESTABLISHED状态,可以进行读写数据了。

四次挥手(断开连接)

所谓四次挥手听着名字就是要分开的节奏,这里的四次挥手就是终止TCP连接,就是一方要断开连接的时候,需要客户端和服务器之间发送4个包(或3个,捎带应答)以确认连接的断开。

四次挥手
由于TCP连接时全双工的,每个方向都必须要单独进行关闭,原则是当一方完成数据发送任务后,发送一个FIN(结束报文段) ,对端发送一个ACK,并发送一个FIN也请求断开连接

建立链接的时候发送的SYN和ACK都是内核控制发送的,但是在断开连接的时候,发送的FIN是调用Close函数触发的,ACK还是内核控制回复

  • 第一次挥手:客户端或者服务器调用Close给对端发生了FIN,暂且将第一次发生FIN的一端叫做主动端。
  • 第二次挥手:对端收到FIN,内核返回ACK。
  • 第三次挥手:对端发送FIn,等待返回ACK。
  • 第四次挥手:主动端返回ACK,并进入TIME_WAIT状态,保证对端收到ACK并关闭。
    四次挥手完成,客户端和服务器正常关闭。

四次挥手主动端的状态变化

  • ESTABLISHED->FIN_WAIT_1:主动端调用Close,向被动端发送结束报文段,同时进入FIN_WAIT_1;
  • FIN_WAIT_1->FIN_WAIT_2:主动端收到结束报文段的确认,则进入FIN_WAIT_2,开始等待被动端的结束报文段
  • FIN_WAIT_2->TIME_WAIT:主动端收到被动端的结束报文段,进入TIME_WAIT,并发送LAST_ACK;
  • TIME_WAIT->CLOSE: 主动端要等待一个2MSL的时间,才会进入CLOSED状态;

四次挥手对端的状态变化

  • ESTABLISHED->CLOSE_WAIT:当主动端调用Close关闭连接,被动端收到结束报文段,被动端进入CLOSE_WAIT;
  • CLOSE_WAIT->LAST_ACK:进入CLOSE_WAIT后说明被动端准备断开连接(需要处理之前的数据);当被动端调用Close关闭连接时,会向主动段发送FIN,此时被动端进入LAST_WAIT状态,等待最后一个ACK到来。
  • LAST_ACK->CLOSE:被动端收到了对FIN的ACK,彻底关闭。

重要的TCP状态:

  1. LISTEN 服务器启动,等待连接。好比手机开机,信号良好,等别人给你打电话。
  2. ESTABLISHED 连接建立成功,可进行数据发送和接受了
  3. CLOSE_WAIT 等待调用Close函数,对端已经执行过close。如果服务器端出现了大量的CLOSE_WAIT状态,那是因为代码中忘记调用Close函数(代码有bug)。
  4. TIME_WAIT谁主动断开连接谁进入TIME_WAIT状态,主动放发送FIN请求断开连接后,接收到对端返回的ACK后,主动方进入TIME_CLOSE,为了防止出现最后一个ACK丢包的情况。即使客户端的程序已经退出,这个状态仍然可能存在。这个状态会存在2*MSL(一个MSL的时间是发生一个ACK所消耗的时间)的时间,如果这个时间等完了还没收到对方超时重传发生的FIN则就认为最后一个ACK对端已经收到,对端已经关闭。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值