一 TCP:传输控制协议报文格式

1 TCP服务

  • 提供面向连接、可靠的字节流服务

  • 面向连接意味着两方通信,不支持多播和广播

  • 可靠性的支持

    • 应用数据被分割成TCP认为最适合发送的数据块。由TCP传递给IP的信息单位称为报文段或段(segment)。
    • 当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
    • 当TCP收到发自TCP连接另一端的数据,它将响应一个确认
    • TCP将保持它首部和数据的检验和
    • TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。
    • IP数据报会发生重复,TCP的接收端必须丢弃重复的数据。
    • TCP还能提供流量控制,TCP连接的每一方都有固定大小的缓冲空间,防止较快主机致使较慢主机的缓冲区溢出。
    • TCP对字节流的内容不作任何解释。对字节流的解释由TCP连接双方的应用层解释。

2 TCP首部

  • TCP首部为20个字节
  • 端口号和目的端口号 :4个字节,用于寻找发端与收端的应用进程。
  • 32位序号:4个字节,用于识别从TCP发端向收端发送的数据字节流,循环利用,逐个递增。
  • 32位确认序号:4个字节,上次已成功收到数据字节序号加1(只有在ACK标志为1时,该字段才有效)
  • 首部长度:4位,用于标识首部的长度,即为5 * 4~15 * 4字节等于20~60字节(固定报头(20字节) + 可选选项)
  • 标志比特:
    • URG:紧急指针
    • ACK:确认序号有效
    • PSH:接受方应尽快将报文段交给应用层
    • RST:重建连接
    • SYN:同步序号用来发起一个连接
    • FIN:发端完成发送任务
  • 窗口大小:用于流量控制,最大为65535字节(16位)
  • 检验和:覆盖整个TCP报文段(TCP首部和数据),发端计算和存储,收端验证
  • 紧急指针:当URG为1时,才有效。

二 TCP连接的建立与终止

1 连接的建立与终止

(1)建立连接协议(三次握手连接)

  • Client发送SYN段指明打算连接Serer的端口以及初始序号(ISN),SYN为1
  • Server响应Server的初始序号(ISN)作为应答,同时将确认序号设置为Client的ISN+1以对Client的SYN报文进行确认。
  • Client将确认序号设置为Server的ISN+1以对Server的SYN报文进行确认。

(2)WireShark抓包分析三次握手连接

# client的SYN报文
Transmission Control Protocol, Src Port: 1682, Dst Port: 1883, Seq: 0, Len: 0
Source Port: 1682 # 源端口
Destination Port: 1883 # 目标端口
Sequence number: 0 (relative sequence number) # 序号
Acknowledgment number: 0 # 确认序号
1000 .... = Header Length: 32 bytes (8) # 首部长度
Flags: 0x002 (SYN) # 标识符
Window size value: 64240 # 窗口大小
Checksum: 0xa6f3 [unverified] # 检验和
Urgent pointer: 0 # 由于URG为0,所以紧急指针为0
Options: (12 bytes), Maximum segment size, No-Operation (NOP), Window scale, No-Operation (NOP), No-Operation (NOP), SACK permitted # 可选选项,后续讲解
TCP Option - Maximum segment size: 1460 bytes # 最大报文端长度
TCP Option - No-Operation (NOP) # 无操作
TCP Option - Window scale: 8 (multiply by 256) # 窗口扩大因子
TCP Option - No-Operation (NOP)
TCP Option - No-Operation (NOP)
TCP Option - SACK permitted # server的响应报文和SYN报文
Transmission Control Protocol, Src Port: 1883, Dst Port: 1682, Seq: 0, Ack: 1, Len: 0
Source Port: 1883
Destination Port: 1682
Sequence number: 0 (relative sequence number)
Acknowledgment number: 1 (relative ack number) # client的Squence number plus one
1000 .... = Header Length: 32 bytes (8)
Flags: 0x012 (SYN, ACK) # 设置SYN和ACK(响应)
Window size value: 14600
Checksum: 0xfd7c [unverified]
Urgent pointer: 0
Options: (12 bytes), Maximum segment size, No-Operation (NOP), No-Operation (NOP), SACK permitted, No-Operation (NOP), Window scale
TCP Option - Maximum segment size: 1412 bytes
TCP Option - No-Operation (NOP)
TCP Option - No-Operation (NOP)
TCP Option - SACK permitted
TCP Option - No-Operation (NOP)
TCP Option - Window scale: 6 (multiply by 64) # client的响应报文
Transmission Control Protocol, Src Port: 1682, Dst Port: 1883, Seq: 1, Ack: 1, Len: 0
Source Port: 1682
Destination Port: 1883
Sequence number: 1 (relative sequence number)
Acknowledgment number: 1 (relative ack number)
0101 .... = Header Length: 20 bytes (5)
Flags: 0x010 (ACK)
Window size value: 259
Checksum: 0xa6e7 [unverified]
Urgent pointer: 0

(3)连接终止协议

  • Client发送FIN报文,此时Client不再发送业务数据到Server,并等待Server的响应报文(Client应用程序关闭)
  • Server收到Client的报文,响应ACK报文。
  • Server发送FIN报文,此时双方都不再发送业务数据数据,并等待Client的响应报文(Server应用程序关闭))
  • Server收到Client的ACK报文即终止连接。

(4)WireShark抓包分析正常关闭

# Client发送FIN报文
Transmission Control Protocol, Src Port: 1682, Dst Port: 1883, Seq: 3, Ack: 1, Len: 0
Source Port: 1682
Destination Port: 1883
Sequence number: 3 (relative sequence number)
Acknowledgment number: 1 (relative ack number)
0101 .... = Header Length: 20 bytes (5)
Flags: 0x011 (FIN, ACK) # ACK是由于需要响应先前的交互
Window size value: 259
Checksum: 0xa6e7 [unverified]
Urgent pointer: 0 # Server发送ACK
Transmission Control Protocol, Src Port: 1883, Dst Port: 1682, Seq: 1, Ack: 4, Len: 0
Source Port: 1883
Destination Port: 1682
Sequence number: 1 (relative sequence number)
Acknowledgment number: 4 (relative ack number)
0101 .... = Header Length: 20 bytes (5)
Flags: 0x011 (FIN, ACK)
Window size value: 229
Checksum: 0x759f [unverified]
Urgent pointer: 0 # Server发送FIN
Transmission Control Protocol, Src Port: 1883, Dst Port: 1682, Seq: 1, Ack: 4, Len: 0
Source Port: 1883
Destination Port: 1682
Sequence number: 1 (relative sequence number)
Acknowledgment number: 4 (relative ack number)
0101 .... = Header Length: 20 bytes (5)
Flags: 0x011 (FIN, ACK)
Window size value: 229
Checksum: 0x759f [unverified]
Urgent pointer: 0 # Client发送ACK
Transmission Control Protocol, Src Port: 1682, Dst Port: 1883, Seq: 4, Ack: 2, Len: 0
Source Port: 1682
Destination Port: 1883
Sequence number: 4 (relative sequence number)
Acknowledgment number: 2 (relative ack number)
0101 .... = Header Length: 20 bytes (5)
Flags: 0x010 (ACK)
Window size value: 259
Checksum: 0xa6e7 [unverified]
Urgent pointer: 0

2 连接建立的超时重试

  • 第一次超时
  • 6秒后重试
  • 24秒后重试
  • ......
  • 非固定,可调整

3 最大报文段长度:MSS

  • 最大报文长度(MSS)表示TCP传往另一端的最大块数据的长度。
  • 默认536字节,超出需要分节(Segment),该值来源于IPv4的最小重组缓冲区大小(576字节),IP首部+TCP首部为40字节,所以传输数据为576-40=536字节。

4 TCP的半关闭

  • TCP提供了连接的一端在结束它的发送后还能接受来自另一端数据的能力。
  • 即我已经完成了数据传送,因此发送一个文件结束(FIN)给另一端,但我还想接收另一端发来的数据,直到它给我发来文件结束(FIN)

5 复位报文段:RST

(1)发到不存在的端口的连接请求

(2)异常终止一个连接

# 某一端直接关闭连接
Transmission Control Protocol, Src Port: 2446, Dst Port: 1883, Seq: 1, Ack: 1, Len: 0
Source Port: 2446
Destination Port: 1883
Sequence number: 1 (relative sequence number)
Acknowledgment number: 1 (relative ack number)
0101 .... = Header Length: 20 bytes (5)
Flags: 0x014 (RST, ACK) # 复位报文
Window size value: 0
Checksum: 0xa6e7 [unverified]
Urgent pointer: 0
  • 优点

    • 应用程序丢弃任何代发的数据并立即发送复位报文段
    • RST的接收方会区分另一端执行的是异常关闭还是正常关闭

(3)检测半打开连接

  • 半打开:一方终止,一方还不知道。
  • 出现原因:掉电(模拟机直接关闭即可)

6 同时打开

  • 双方同时执行主动打开,即每一方都发送SYN,但最终只建立了一个连接。
  • 模拟这个可以通过辣鸡VPN进行测试,如亚马逊的免费云(即往返时间比较长,便于模拟)。

7 同时关闭

  • 同时关闭与正常关闭使用的段交换数目相同。

8 TCP选项

  • 选项表结束:kind=0(1字节)
  • 无操作:kind=1(1字节)
  • 最大报文长度:kind=2(1字节),len=4(1字节),最大报文段长度(2字节)
  • 窗口扩大因子:kind=3(1字节),len=3(1字节),移位数(1字节)
  • 时间戳:kind=8(1字节),len=10(1字节),时间戳值(4字节),时间戳回显应答(4字节)
# 发送MSS
TCP Option - Maximum segment size: 1460 bytes
Kind: Maximum Segment Size (2)
Length: 4
MSS Value: 1460
# NOP
TCP Option - No-Operation (NOP)
Kind: No-Operation (1)
# 窗口扩大因子
TCP Option - Window scale: 8 (multiply by 256)
Kind: Window Scale (3)
Length: 3
Shift count: 8

三 未来计划

  • 学习TCP是为了更好地理解MQTT协议(即自顶向下的学习方式,以前自底向上学过一段时间,效果一般,因为没有应用场景)
  • TCP学完之后,将补充HTTP协议(基于TCP协议)
  • HTTP协议之后,将学习WebSocket协议,并最终回到MQTT协议(能够基于WebSocket协议进行传输)

TCP协议探究(一):报文格式与连接建立终止的更多相关文章

  1. TCP/IP 数据包报文格式(IP包、TCP报头、UDP报头)(转)

    reference:http://blog.51cto.com/lyhbwwk/2162568                    https://blog.csdn.net/wangzhen209 ...

  2. TCP协议探究(四):定时器

    1 概述 重传定时器:使用于当希望收到另一端的确认. 坚持(persist)定时器:使窗口大小信息保持不断流动,即使另一端关闭了其接收窗口 保活(keepalive)定时器:用于检测一个空闲连接的另一 ...

  3. TCP协议探究(二):超时与重试

    1 概述 TCP提供可靠的运输层. 可靠性保证之一:确认从另一端收到的数据. 但数据和确认都有可能会丢失.TCP通过在发送时设置一个定时器来解决这种问题. 如果当定时器溢出时还没有收到确认,它就重传该 ...

  4. HTTP协议中的报文格式

    按照传输过程,HTTP 报文分为请求报文和响应报文.请求报文和响应报文的结构差不多,这里只对 HTTP 请求报文做一个总结.HTTP 请求报文由 请求行.请求头.请求体(请求数据).空行 四个部分组成 ...

  5. TCP协议探究(三):RTT、滑动窗口和阻塞处理

    1 RTT算法 1.1 概述 上一节说了重传机制需要设置一个重传超时值(RTO,Retransmission TimeOut),RTO设长了,重发太慢:设短了,可能导致包没有丢,就重发了,可能导致雪崩 ...

  6. http,tcp,udp的报文格式

    http请求报文与响应报文:https://blog.csdn.net/qq_26565861/article/details/80969960 tcp与udp报文:https://www.cnblo ...

  7. HTTP协议报文格式

    HTTP协议报文格式 接下来我们看看HTTP协议(Hypertext Transfer Protocol――超文本传输协议)浏览器端(客户端)向WEB服务器端访问页面的过程和HTTP协议报文的格式. ...

  8. TCP协议承载的DNS报文,DNS报文首部前多出两个字节的DNS报文长度字段,是何意义?

    一.TCP报文头部简介 ●源.目标端口号字段:占16比特.TCP协议通过使用"端口"来标识源端和目标端的应用进程.端口号可以使用0到65535之间的任何数字.在收到服务请求时,操作 ...

  9. TCP协议设计原理

    TCP协议设计原理 最近去了解TCP协议,发现这是一个特别值得深思的协议.在本篇博客中,不会长篇大论的给大家介绍TCP协议特点.包头格式以及TCP的连接和断开等基本原理,而是会带大家深入理解为什么要这 ...

随机推荐

  1. [转]SQL 读取表结构

    1.Sql SELECT column_name as FName,data_type as FType,CHARACTER_MAXIMUM_LENGTH as FLen from informati ...

  2. js传值到后台乱码问题

    1.前台js的路径 var addurl1="ldcOrderController.do?goods&orderGoodsExtra="+encodeURI(encodeU ...

  3. Flask中current_app和g对象

      Flask零基础到项目实战(七)请求方法.g对象和钩子函数 一.get方法 二.post方法 post请求在模板中要注意几点: input标签中,要写name来标识这个value的key,方便后台 ...

  4. 安装mysql问题解决

    [root@apollo init.d]# /etc/init.d/mysqld startmy_print_defaults: Can't read dir of '/etc/my.cnf.' (E ...

  5. golang web框架设计7:整合框架

    把前面写好的路由器,控制器,日志,都整合在一起 全局变量和初始化 定义一些框架的全局变量 var ( BeeApp *App AppName string AppPath string StaticD ...

  6. Flutter 状态管理 flutter_Provide

    项目的商品类别页面将大量的出现类和类中间的状态变化,这就需要状态管理.现在Flutter的状态管理方案很多,redux.bloc.state.Provide. Scoped Model : 最早的状态 ...

  7. Java工程师学习指南第2部分:JavaWeb技术世界

    本文整理了微信公众号[Java技术江湖]发表和转载过的Java Web优质文章,想看到更多Java技术文章,就赶紧关注吧. IDEA中的Maven实战 老师,免费版的IDEA为啥不能使用Tomcat? ...

  8. NDK学习笔记-JNI的异常处理与缓存策略

    在使用JNI的时候,可能会产生异常,此时就需要对异常进行处理 异常处理 JNI抛出Throwable异常,在Java层可以用Throwable捕捉 而在C只有清空异常这种处理 但如果在JNI中通过Th ...

  9. CSharp实体生成器

    专门为C#开发人员定制的一个实体生成器,以往的生成器功能达到了,但是很多细节未考虑到,所以我借鉴“先人”的一些已有的东西,重新定制了一个.当然,需要源码的同学,直接使用IL Spy这个小工具就可以看到 ...

  10. Goahead 编译

    目录 Goahead 目录说明 Ubuntu编译 交叉编译 方便测试 参考 title: Goahead date: 2019/11/6 09:45:01 toc: true --- Goahead ...