当前位置: 首页 > news >正文

TCP头部详解

以下是TCP头部结构:
在这里插入图片描述
结构体定义:

struct tcphdr
{
	unsigned short sport;
	unsigned short dport;

	unsigned int seqnum;
	unsigned int acknum;

	unsigned char hdrlen : 4,
		recv : 4;

	unsigned char cwr : 1,
		ece : 1,
		urg : 1,
		ack : 1,
		psh : 1,
		rst : 1,
		sys : 1,
		fin : 1;

	unsigned short cwnd;
	unsigned short check;
	unsigned short urg_pointer;
};

sizeof(tcphdr) = 20

字段含义详解:
16位源端口号和目的端口号:告知主机该报文段是来自哪里(源端口Source Port)以及传给哪个上层协议或应用程序(目的端口Destination Port)的。进行TCP通信时,客户端通常使用系统自动选择的临时端口号,而服务器则使用知名服务端口号(比如DNS协议对应端口53,HTTP协议对应80,这些端口号可在/etc/services文件中找到)。
32位序号:一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。假设主机A和主机B进行TCP通信,A发送给B的第一个TCP报文段中,序号值被系统初始化为某个随机值ISN(Initial Sequence Number,初始序号值)。那么在该传输方向上(从A到B),后续的TCP报文段中序号值将被系统设置成ISN加上该报文段所携带数据的第一个字节在整个字节流中的偏移。例如,某个TCP报文段传送的数据是字节流中的第1025~2048字节,那么该报文段的序号值就是ISN+1025.另外一个传输方向(从B到A)的TCP报文段的序号值也具有相同的含义。
32位确认号(acknowledgement number):用作对另一方发送来的TCP报文段的响应。其值是收到的TCP报文段的序号值加1。假设主机A和主机B进行TCP通信,那么A发送出的TCP报文段不仅携带自己的序号,而且包含对B发送来的TCP报文段的确认号。反之,B发送出的TCP报文段也同时携带自己的序号和对A发送来的报文段的确认号。
4位头部长度(header length):标识该TCP头部有多少个32bit字(4字节)。因为4位最大能标识15,所以TCP头部最长是60字节。
6位标志位包含如下几项:

    URG标志,表示紧急指针(urgent pointer)是否有效。

    ACK标志,表示确认号是否有效。我们称携带ACK标识的TCP报文段为确认报文段。

    PSH标志,提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间(如果应用程序不将接收

    到的数据读走,它们就会一直停留在TCP接收缓冲区中)。

     RST标志,表示要求对方重新建立连接。我们称携带RST标志的TCP报文段为复位报文段。

     SYN标志,表示请求建立一个连接。我们称携带SYN标志的TCP报文段为同步报文段。

     FIN标志,表示通知对方本端要关闭连接了。我们称携带FIN标志的TCP报文段为结束报文段。

16位窗口大小(window size):是TCP流量控制的一个手段。这里说的窗口,指的是接收通告窗口(Receiver Window,RWND)。它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。
16位校验和(TCP check sum):由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分。这也是TCP可靠传输的一个重要保障。
16位紧急指针(urgent pointer):是一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此,确切地说,这个字段是紧急指针相对当前序号的偏移,不妨称之为紧急偏移。TCP的紧急指针是发送端向接收端发送紧急数据的方法。
TCP头部选项:TCP头部的最后一个选项字段(options)是可变长的可选信息。这部分最多包含40字节,因为TCP头部最长是60字节(其中还包含前面讨论的20字节的固定部分)。典型的TCP头部选项结构如下图所示。
在这里插入图片描述
选项的第一个字段kind说明选项的类型。有的TCP选项没有后面两个字段,仅包含1字节的kind字段。第二个字段length(如果有的的话)指定该选项的总长度,该长度包括kind字段和length字段占据的2字节。第三个字段info(如果有的话)是选项的具体信息。常见的TCP选项有7种,如下图
在这里插入图片描述
kind=0是选项表结束选项。

kind=1是空操作(nop)选项,没有特殊含义,一般用于将TCP选项的总长度填充为4字节的整数倍。

kind=2是最大报文段长度选项。TCP连接初始化时,通信双方使用该选项来协商最大报文段长度(Max Segement Size,MSS)。TCP模块通常将MSS设置为(MTU-40)字节(减掉的这40字节包括20字节的TCP头部和20字节的IP头部)。这样携带TCP报文段的IP数据报的长度就不会超过MTU(假设TCP头部和IP头部都不包含选项字段,并且这也是一般情况),从而避免本机发生IP分片。对以太网而言,MSS值是1460(1500-40)字节。

kind=3是窗口扩大因子选项。TCP连接初始化时,通信双方使用该选项来协商接收通告窗口的扩大因子。在TCP的头部中,接收通告窗口大小时用16位表示的,故最大为65535字节,但实际上TCP模块允许的接收通告窗口大小远不止这个数(为了提高TCP通信的吞吐量)。窗口扩大因子解决了这个问题。假设TCP头部中的接收通告窗口大小是N乘2的M次方,或者说N左移M位。注意,M的取值范围是0~14。我们可以通过修改/proc/sys/net/ipv4/tcp_window_scaling内核变量来启用或关闭窗口扩大因子选项。

kind=5是SACK实际工作的选项。该选项的参数告诉发送方本端已经收到并缓存的不连续的数据块,从而让发送端可以据此检查并重发丢失的数据块。每个块边沿(edge of block)参数包含一个4字节的序号。其中块左边沿表示不连续块的第一个数据的序号,而块右边沿则表示不连续块的最后一个数据的序号的下一个序号。这样一对参数(块左边沿和块右边沿)之间的数据是没有收到的。因为一个块信息占用8字节,所以TCP头部选项中实际上最多可以包含4个这样的不连续数据块(考虑选项类型和长度占用的2字节)。

kind=8是时间戳选项。该选项提供了较为准确的计算通信双方之间的回路时间(Round Trip Time,RTT)的方法,从而为TCP流量控制提供重要信息。我们可以通过修改/proc/sys/net/ipv4/tcp_timestamps内核变量来启用或关闭时间戳选项。

相关文章:

  • 常见的排序算法原理及c代码实现
  • stl之remove、erase算法与元素的删除
  • docker学习之旅二:docker基本命令
  • docker学习之旅一:ubuntu下安装docker+配置阿里源
  • redis-跳跃表zskiplist
  • redis集群介绍与搭建
  • Linux系统命令与网络、磁盘参数和日志监控命令
  • mysql 8.0版本修改密码
  • 解决Navicat 连接mysql报错:Can‘t connect to MYSQL server on “ip address“(10061)
  • jsoncons使用之: 构造json
  • 使用reserve来避免不必要的内存重新分配
  • redis 编译报错 zmalloc.h:50:10: fatal error: jemalloc/jemalloc.h: 没有那个文件或目录
  • linux下hiredis安装、C接口编程
  • redis源码学习之数据结构---双向链表
  • redis源码分析--事件驱动模型
  • 345-反转字符串中的元音字母
  • express如何解决request entity too large问题
  • React系列之 Redux 架构模式
  • spring boot 整合mybatis 无法输出sql的问题
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • vue-cli在webpack的配置文件探究
  • Web设计流程优化:网页效果图设计新思路
  • 闭包,sync使用细节
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 基于Android乐音识别(2)
  • ------- 计算机网络基础
  • 配置 PM2 实现代码自动发布
  • 小程序滚动组件,左边导航栏与右边内容联动效果实现
  • 延迟脚本的方式
  • 用mpvue开发微信小程序
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (篇九)MySQL常用内置函数
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)mysql使用Navicat 导出和导入数据库
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .chm格式文件如何阅读
  • .NET Compact Framework 3.5 支持 WCF 的子集
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .Net 中Partitioner static与dynamic的性能对比
  • .net分布式压力测试工具(Beetle.DT)
  • .vimrc php,修改home目录下的.vimrc文件,vim配置php高亮显示
  • @RequestBody详解:用于获取请求体中的Json格式参数
  • @Transactional注解下,循环取序列的值,但得到的值都相同的问题
  • [BZOJ1008][HNOI2008]越狱
  • [C#][DevPress]事件委托的使用
  • [C++]AVL树怎么转
  • [CDOJ 1343] 卿学姐失恋了
  • [CodeForces-759D]Bacterial Melee
  • [Excel VBA]单元格区域引用方式的小结
  • [IMX6DL] CPU频率调节模式以及降频方法
  • [Java基础]—JDBC
  • [java面试]宇信易诚 广州分公司 java笔试题目回忆录