一 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. fsLayuiPlugin数据表格弹出form表单说明

    fsLayuiPlugin 是一个基于layui的快速开发插件,支持数据表格增删改查操作,提供通用的组件,通过配置html实现数据请求,减少前端js重复开发的工作. GitHub下载 码云下载 测试环 ...

  2. idea内存不足或过大闪退

    昨天在码云找了个开源后台项目https://gitee.com/shuzheng/zheng,各种修改后终于跑起来了, 运行没多久就提示内存不足,安装目录配置虚拟机最大可用内存为512M idea弹窗 ...

  3. 安装windows下安装mysql

    参考文档:https://www.cnblogs.com/reyinever/p/8551977.html  https://www.jb51.net/article/151213.htm 首先下载m ...

  4. 解决jenkins日志爆满 DNS查询错误

    一.故障 公司的jenkins因为日志量太大把磁盘占满,进而影响了其他程序,仔细一看日志文件"/var/log/jenkins/jenkins.log"几分钟产生了30G的日志 日 ...

  5. android studio gradle国内代理设置

    android studio在开始都各项目之前都会遇到 gradle 的同步,而在同步过程中很多依赖下载特别慢甚至出现无法现在的情况,有的时候等的时间特别长,甚至要一天,关键是等了大半天之后突然报错, ...

  6. Flask request 属性详解

    Flask request 属性详解 一.关于request在Flask的官方文档中是这样介绍request的:对于 Web 应用,与客户端发送给服务器的数据交互至关重要.在 Flask 中由全局的 ...

  7. [Scikit-learn] 1.5 Generalized Linear Models - SGD for Regression

    梯度下降 一.亲手实现“梯度下降” 以下内容其实就是<手动实现简单的梯度下降>. 神经网络的实践笔记,主要包括: Logistic分类函数 反向传播相关内容 Link: http://pe ...

  8. find_player 不查找已经晕到玩家的问题

    问题场景: 游戏中出现个BUG,是关于登陆后出现分身的问题. 查找当前登陆者的身份 是否之前存在相同的角色实例,当玩家昏迷状态时 使用 find_player是找不到这个玩家的,所以 玩家利用角色昏迷 ...

  9. MLE & MAP

    MLE & MAP : data / model parameter MLE: (1) keep the data fixed(i.e., it has been observed) and ...

  10. jQuery.fn.extend与jQuery.extend的区别

    jquery 本身并不提供 jQuery.color() 这个方法,如果我们需要对jQuery本身提供的方法进行扩展,则我们就需要是用jQuery.fn.extend: jQuery.fn.exten ...