tcp协议--报文格式,连接建立,可靠传输,拥塞控制

0.Tcp报文帧格式

  • 源端口:发送端的端口号
  • 目的端口:接收端的端口号
  • 序号(seq):比如一个数据包的序号为301,携带的数据长度有100个字节,那么最后一个字节序号就是400,那么下一个数据包开始的序号就是401
  • 确认号(ack):期望收到对方的下一个报文段的数据的第一个字节序号。

A-->B:发过来的数据包,序号(seq)为501,数据长度为200(501~700)

B-->A:这个确认号(ACK)就是701,代表B期望收到A发送的下一个数据序号是701

总之:确认号 = N,代表成功收到了N-1个数据包。

  • 数据偏移:??
  • URG:表示此报文为紧急传输数据,比如在ftp下包的时候,用户点了取消(CTRL + c),那么这个包不用继续传了,所以这里需要置位。
  • ACK:确认位,TCP规定,建立连接后的所有传输报文都需要把ACK置1
  • PSH:当两个进程交互的时候,需要一些报文希望对方可以立刻响应,这种情况接收端收到了这个报文就会尽快处理。
  • RST:当tcp连接出现严重错误,需要断开连接,RST会置1.
  • SYN:再建立连接的时候同步序号。

tcp三次握手建立连接的时候SYN == 1

A-->B发送连接请求:SYN = 1,ACK =0代表请求连接。

B-->A发送响应报文:SYN = 1,ACK =1表示同意连接。

  • 终止FIN:用来释放连接,当FIN = 1,表明发送方请求断开连接。

tcp的4次回收断开连接

  • 窗口:这个是接收方向发送方要求,发送端的窗口大小。是在动态变化的。

比如A-->B发送了“确认号701,窗口1000”的报文,即A告诉B:B发送接下来报文需要考虑到:我还能收1000个字节的数据。

  • 校验和:看前面的数据对不对
  • 紧急指针:在URG=1的时候才有意义,紧急指针指出了紧急数据的末尾在报文段中的位置。
  • 选项:长度可变,最长可达40字节。

1. 面向连接

  • tcp三次握手

在这里插入图片描述

  1.  client-->server: SYN = 1(连接报文) ,seq = x (这是client发出的第X个包)
  2. server-->client:SYN=1(连接报文),ack= x+1(server收到了client的第X个包,Sever期待client发的下一个包是X + 1)  ,seq = Y(这是server发出的第Y个包),ACK = 1规定。
  3. client-->server:ack = Y+1 (client收到了server的第X个包,client期待Sever发的下一个包是X + 1) seq = x+1 。ACK=1规定。
  • tcp三次握手包(通过 curl baidu.com抓包)

  1.  38740->80 : [SYN = 1]  Seq = x = 0
  2. 80->38740:   [SYN = 1, ACK= 1] Seq = y = 0, Ack = x + 1 = 1
  3. 38740->80:      [ACK = 1]  Seq = x + 1 = 1, Ack = y + 1 = 1
  •  tcp四次挥手

在这里插入图片描述

 (1) client-->server:

  • FIN = 1请求断开连接
  • seq = u 客户端发的第u个报文

(2)server-->client:

  • ACK = 1规定
  • seq = v 
  • ack = u+1 (收到了client的第u条报文,期望收到u+1的报文)

 (3) server-->client:

  • FIN = 1请求断开连接
  • ACK = 1
  • ack = u+1 (收到了client的第u条报文,期望收到u+1的报文)
  • seq = w

(4)client-->server:

  • ACK = 1规定
  • seq = u+1
  • ack = w+1

tcp四次挥手包(通过 curl baidu.com抓包)

  1.  38740->80:  [FIN = 1 ACK = 1] Seq = u = 74     [注: ACK =  1 代表上一条报文的响应]
  2. 80->38740:   [ACK = 1] Seq = v = 387,  Ack = u + 1 = 75
  3. 80->38740:   [FIN = 1, ACK = 1] Seq = w = 387, Ack = u + 1 = 75
  4. 38740->80:   [ACK = 1]  Seq = u+ 1 = 75, Ack = w + 1 = 388

4.3 TCP 实战抓包分析 | 小林coding

  • tcp三次挥手:(如下图两个三次挥手。)

在调试mqtt的时候,mqtt的client端断开连接,发现tcp挥手是三次挥手。查了下资料:是服务端)在 TCP 挥手过程中,「没有数据要发送」并且「开启了 TCP 延迟确认机制」,那么第二和第三次挥手就会合并传输,这样就出现了三次挥手

2.可靠传输原理

  • 停止等待协议

  1. 因为数据链路层的MTU有限制(就算1500),然后向上限制了应用层,传输层,网络层的报文大小。比如在应用层发了一个3000大小的数据帧,到了网络层,就需要对这个数据帧分包,于是把要传输的每一个数据单元称作“分组”。
  2. 停止等待:就是每发一个分组,就停止发送,等待对方的确认,收到确认报文后,再发下一个分组。
  3. 超时重传:当主机A发送给主机B一个数据包,A会有一个超时时间(通过超时计时器实现),当大于这个时间主机A没有收到主机B反馈的确认报文,A就会重传这个数据包。

停止等待协议已经可以满足可靠传输了,但有一个致命缺点:效率太低。发送方发送一个数据包之后便进入等待,这个期间并没有干任何事,浪费了资源。解决的方法是:连续发送数据包

  • 自动重传请求ARQ

发送消息的模型如下, 但是这样也不行,万一包过大,一下发完了,缓冲区肯定受不了,所以需要对发送的数据包的量做控制,这叫做TCP的流量控制:具体实现手段就是滑动窗口

  • 滑动窗口:

如下图:发送端缓冲区一共有8个数据包,滑动窗口为4。

  1. 发送端滑动窗口为4,发送0,1,2,3四个数据包
  2. 接收端回复0,1的接受肯定响应。发送端收到。发送端的发送窗口后移两个。
  3. 发送端这个时候可发送4,5。

按照上述的流程即可通过滑动窗口发送报文。但这样还是存在问题,过多的来自接收端的确认响应,为了提高效率,可用累计确认的方法。接收端不用收到每个数据包都回复,可累计收到几个包之后在回复一个响应报文。比如接收到收到了0,1,2,3后,回复给发送端一个3就可代表收到了0,1,2,3 

但这样也会带来新的问题:丢包了咋整,比如发送端发了0 1 2 3,接收端收到了0 1 3,按照之前的逻辑,需要重传2,3 但是3是没必要重传的,所以就有了选择确认SACK位(用4个指针确认需要重传的字节流窗口)。

  • 可靠传输总结:

  1. 通过ARQ协议,用发送-确认回复模式来保证数据包的可靠传输
  2. 给字节编号:来确认每个包是重传,还是新的数据包
  3. 超时重传
  4. 滑动窗口实现流量控制
  5. 累计确认+选择确认来提高回复与重传的效率

2.拥塞控制

拥塞控制的重点有4个:慢开始、快恢复、快重传、拥塞避免

塞控制的解决方法是流量控制,流量控制的实现是滑动窗口

Y轴表示的是发送方窗口大小,X轴表示的是发送的轮次(不是字节编号)。

  • 简单的说就是不断地调整的调整滑动窗口的大小,来达到对网络的最大效率使用。

3. tcp调用send/recv之后发生了什么?

摘自:深入理解tcp网络编程中的send和recv_hycxag的博客-CSDN博客_sendrecv什么意思

  • send返回之时,数据不一定会发送到对端去、,send仅仅是把应用层buffer的数据拷贝进socket的内核发送buffer(tcp缓存)中。
  • 对于TCP,如果应用进程一直没有读取,buffer满了之后,发生的动作是:通知对端TCP协议中的窗口关闭。这个便是滑动窗口的实现。保证TCP套接口接收缓冲区不会溢出,从而保证了TCP是可靠传输。因为对方不允许发出超过所通告窗口大小的数据。 这就是TCP的流量控制,如果对方无视窗口大小而发出了超过窗口大小的数据,则接收方TCP将丢弃它。
  • 每个UDP socket都有一个接收缓冲区,没有发送缓冲区,从概念上来说就是只要有数据就发,不管对方是否可以正确接收,所以不缓冲,不需要发送缓冲区。

参考:掌握这28张图,面试再也不怕被问TCP知识了_一口Linux的博客-CSDN博客

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值