三次握手与四次挥手

三次握手与四次挥手

本章主要介绍关于三次握手,四次挥手基本概念以及其中涉及到的posix api

1. TCP 头部解读

在这里插入图片描述
源端口目的端口 :用于标识该报文用于主机的哪个进程,像我们熟知的ssh 协议,常用的目的端口号是22
sequence number(序列号) :表示报文段数据中的第一个字节号,
Acknowledgment number(确认号):该确认号的发送方期待接收的下一个序列号
ACK:确认, 占据1bit位, 置1表示该报文的确认号有效
RST:重置连接
SYN:用于初始化一个连接的序列号
FIN: 表示该报文发送方已经结束向对方发送数据

注:

  1. 进行三次握手过程中,TCP payload 是不包含数据的。

2. 三次握手的过程

三次握手过程描述

在这里插入图片描述

  • 第一次握手:client 端发送SYN = 1的包,server端进行监听接收报文,如果server端接收到了,从server的角度看client 发送能力和server 接收能力是正常的
  • 第二次握手:server 发送一个ACK = 1, SYN = 1的ack包 , ack的数值是在是第一次握手报文的seqnum + 1, 从client角度上看,client的recv 和send 能力是正常的,server 的send和recv能力是正常的
  • 第三次握手:client端发包,一个ACK = 1的包,如果server端recv成功,从server角度看,我第二次从发送ack包有被client 成功接收,而自己的send和recv 功能正常

举一个实际的例子:如果比如一对情侣a, b 需要通过写信进行相互通信。 如果情侣双方需要知道,双方的信件能被正常接收和发送,只需要通过以下操作就可以知晓。

  1. ab 写一封信件,如果b 接收到了。从b的角度能看出a能正常发送信件出来,b也能正常接收信件,。此时从a的角度看,对双方的收发能力不清楚;
  2. 这个时候ba回一封信件,如果a 收到b发送的信件。从a的角度看,a能正常发送和接收信件,b能正常发送信件和接收;从b的角度看,只知道自己能正常接收
  3. ab回一封信,如果b接收到了,从b的角度上看,自己的发送和和接收能力是正常的

网络编程中涉及的posix api

只涉及到了三次握手的api

  • socket():分配1个套接字fd, 同时分配1个tcb( tcp control block: tcp 控制块)

  • bind(): 通过socket函数返回的fd 与 ip,port 建立映射,本质是在tcb 中设置ip, port

  • listen(): 本质是将tcb 的状态设置为TCP_STATUS_LISTEN, 使得可以接收其他进程的连接请求,用于第一次握手

  • accept(): 该接口是在三次握手成功后,进行数据传输使用

为什么要三次握手

可以确定双方具有发送和接收的能力是正常的,同时同步双方的序列号和确认号
三次握手的主要目的就是同步双方的序列号和确认号,并交换tcp窗口大小信息,
思考:

  1. 为什么要同步双方的序列号和确认发号?
    举一个例子:
    比如有2个商人,甲、乙分别在北京和广州,甲通过网络从乙处订购了比较多的白切鸡,双方通过都借助物流运送货物,由于货物的量比较大,订购的货物用了多辆车进行运输,并给车辆进行顺序编号。在实际的运送过程中,双方都需要知道货物到达的情况,为了应对这种情况呢,比如说甲可以查看已经到达车辆的编号,并给到达的车辆进行排序,如果到达的车辆编号时1, 2,3,4,7,8,这样的话甲就知道,5,6已经没有到达,如果在规定的时间内还没有到达,说明5,6 已经丢失,这时回复给乙5,这样商家就会从5开始重新发货。
    这里面提到的甲收到的车辆号码比作序列号,发送给乙的号码比作确认号

4. 四次挥手

四次挥手过程描述

在这里插入图片描述
注意: 其实通信的双方都能通知对方释放连接
以下以client发送释放连接请求进行描述

  • 第一次挥手:client 向server发送一个FIN = 1, seq = x的报文, 进入 FIN_WAIT_1状态, 告知server 进行需要进行连接关闭
  • 第二次挥手:server 接收到client 的报文后,在发送一个ACK = 1, ack = x + 1的报文,进入CLOSE_WAIT状态 。client 接受到server的 ACK报文后,进入了FIN_WAIT_2状态。
  • 第三次挥手: server 在发送一个FIN = 1, seq = y的报文,进入LAST_ACK状态
  • 第四次挥手: client 接收到报文后,发送一个ACK = 1, ack = y+ 1, 并进入了TIME_WAIT状态

为什么要有四次挥手

其实通信的双方是进行全双工通信的, 比如client发起FIN 报文,之后就需要server的ACK报文,这样才清楚是否有进行通信的server 有接收到FIN报文。同理,同时server 也需要发送FIN报文,之后还是需要client 回复ACK报文。

涉及的posix api

close(), recv():在四次挥手中用于触发连接关闭的请求, 其本质是关闭内核空间分配的套接字。关闭之后,如果内核缓冲区的还是存在数据,client 继续向server 发送内核缓冲区的数据,随后缓冲区为空时发送FIN报文,server 接收到这个FIN 报文,应用层通过调用recv()之后的返回值为0,知晓client是在请求关闭连接

学习链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值