TCP详解

一、TCP报文段结构

在这里插入图片描述
1、源端口号和目的端口号都是16位,范围从(1-65535,0不可用)
2、序列号:在建立连接时由内核生成的随机数作为其初始值,通过 SYN 报文传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。
3、确认号:指下一次「期望」收到的数据的序列号,发送端收到接收方发来的 ACK 确认报文以后,就可以认为在这个序号以前的数据都已经被正常接收。用来解决丢包的问题。
4、控制位:用来标识 TCP 报文是什么类型的报文,比如是 SYN 报文、数据报文、ACK 报文,FIN 报文等。

1、TCP序列号和确认号万能公式

机器发送的 TCP 报文公式如下:

  • 公式一:序列号 = 上一次发送的序列号 +上一次发送的数据长度 len(数据长度)。特殊情况,如果上一次发送的报文是 SYN 报文或者 FIN 报文,则改为上一次发送的序列号 + 1。
  • 公式二:确认号 = 上一次收到的报文中的序列号 + 上一次收到的报文长度len(数据长度)。特殊情况,如果收到的是 SYN 报文或者 FIN 报文,则改为上一次收到的报文中的序列号 + 1。

SYN 报文长度为1
SYNACK报文长度为1
FIN报文长度为1
单纯的ACK报文长度为0

二、TCP建立连接(三次握手)和数据传输

在这里插入图片描述

1、连接建立(三次握手)

  • 1、初始状态:一开始客户端和服务端都是属于关闭(CLOSE)状态,服务端通过
    ServerSocket serverSocket = new ServerSocket(8081,1);开启监听(LISTEN);
  • 2、第一步,客户端的TCP首先向服务器的TCP发送一个特殊的TCP报文段,该报文段被称为SYN报文段。该报文段中不包含应用层数据,但是会将TCP报文段首部中的一个标志位即SYN比特设置为1;因此这个特殊的报文段被称为SYN报文段;另外,客户端会随机的生成一个初始序号(client_isn),并将此编号放置于该报文段的序列号(Seq)字段中;即Seq= client_isn=x此时客户端会进入SYS_SEND状态。
  • 3、第二步、一旦服务器收到了SYN报文,需要确认客户端的报文,会将确认报文中的SYN比特设置为1,ACK比特设置为1,并将该报文中的确认号Ack设置为client_isn+1(公式2),即Ack=client_isn+1,最后服务器会生成自己的初始序列(server_isn),并将之放到报文段的序列号字段上,即Seq=server_isn=y;该报文表示:“我收到了你发起建立连接的SYN分组,该分组带有初始序号client_isn,我同意建立连接,我自己的初始序列是server_isn” 该允许连接的报文段有时被称为SYNACK报文段SYNACK segment,此时服务端进入SYN_RECV状态,并且该连接进入到syn queue 队列中去;
  • 4、 第三步、在客户端收到SYNACK报文段后,需要对该SYNACK报文段确认,需要将ACK设置为1,序列号为Seq= client_isn+1 (公式1)确认号为Ack=server_isn+1(公式2);因为此时连接已经建立,所以SYN被设置为0,并且后续的数据发送SYN字段也被设置为0。TCP规定这个报文段可以携带数据也可以不携带数据,如果不携带数据,那么数据长度就是0,根据上述公式1那么下一个数据报文段的序号仍是 seq = client_isn + 1。这时,客户端进入 ESTABLISHED (已连接) 状态。
  • 5、服务器收到客户的确认后,也进入 ESTABLISHED 状态。

2、数据传输

客户端发送 10 字节的数据,通常 TCP 数据报文的控制位是 [PSH, ACK],此时该 TCP 数据报文的序列号和确认号分别设置为:

  • 1、序列号设置为 client_isn + 1。客户端上一次发送报文是 ACK 报文(第三次握手),该报文的 seq = client_isn + 1,由于是一个单纯的 ACK 报文,没有携带用户数据,所以 len = 0。根据公式 1(序列号 = 上一次发送的序列号 + len),可以得出当前的序列号为 client_isn + 1 + 0,即 client_isn + 1。
  • 2、确认号设置为 server_isn + 1。没错,还是和第三次握手的 ACK 报文的确认号一样,这是因为客户端三次握手之后,发送 TCP 数据报文 之前,如果没有收到服务端的 TCP 数据报文,确认号还是延用上一次的,其实根据==公式 2 ==你也能得到这个结论。
    可以看到,客户端与服务端完成 TCP 三次握手后,发送的第一个 「TCP 数据报文的序列号和确认号」都是和「第三次握手的 ACK 报文中序列号和确认号」一样的。

如果客户端发送的第三次握手 ACK 报文丢失了,处于 SYN_RCVD 状态服务端收到了客户端第一个 TCP 数据报文会发生什么?

发送的第一个 「TCP 数据报文的序列号和确认号」都是和「第三次握手的 ACK 报文中序列号和确认号」一样的,并且该 TCP 数据报文也有将 ACK 标记位置为 1。所以,服务端收到这个数据报文,是可以正常完成连接的建立,然后就可以正常接收这个数据包了。

三、四次挥手

数据传输阶段结束后,客户端发起了 FIN 报文,请求服务端端开该 TCP 连接,此时就进入了 TCP 四次挥手阶段,如下图:
在这里插入图片描述

  • 1、客户端发起第一次挥手。FIN设置为1,ACK设置为1,该报文长度为1;
    序列号为上一次发送的序列号+上一次发送的数据长度,即Seq=client_isn+11;
    确认号是上一次收到的报文中的序列号 +上一次收到的报文长度len,上一次收到的序列号为server_isn+1,因为上一次收到的是单纯的ACK报文,所以长度为0,所以Ack=server_isn+1+0=server_isn+1
  • 2、服务端发起第二次挥手。ACK设置为1,该报文长度为0;
    序列号为上一次发送的序列号+上一次发送的数据长度,即Seq=server_isn+1,因为上一次收到的是单纯的ACK报文,所以长度为0,所以Seq=server_isn+1+0=server_isn+1;
    确认号为上一次收到的报文中的序列号 +上一次收到的报文长度len,上一次收到的是FIN报文,故而长度为1;即Ack=client_isn+11+1=client_isn+12;
  • 3、服务端发起第三次挥手。SYN设置为1,该报文长度为1;
    序列号为上一次发送的序列号+一上次发送的数据长度,因为上一次发送的是单纯的ACK报文,所以长度为0,即Seq=server_isn+1+0=server_isn+1;
    确认号为上一次收到的报文中的序列号 +上一次收到的报文长度len,上一次收到的序列号是client_isn+11,因为收到的是FIN报文,长度为1,所以Ack=client_isn+11+1=client_isn+12;
  • 4、客户端发起第四次挥手。ACK设置为1,该报文长度为0;
    序列号为上一次发送的序列号+一上次发送的数据长度,上一次发送的序列号是client_isn+11,因为发送的是FIN报文,长度为1,所以Seq=client_isn+11+1=client_isn+12(上述图中有误,请注意,懒得改了);
    确认号为上一次收到的报文中的序列号 +上一次收到的报文长度len,上一次收到的序列号为server_isn+1,报文是FIN报文,长度是1;即Ack=server_isn+1+1=server_isn+2(上述图中有误,请注意,懒得改了);

引用

https://zhuanlan.zhihu.com/p/577528304

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/768981.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言数据结构易错知识点(5)(插入排序、选择排序)

插入排序:直接插入排序、希尔排序 选择排序:直接选择排序、堆排序 上述排序都是需要掌握的,但原理不会讲解,网上有很多详尽地解释,本文章主要分享一下代码实现上应当注意的事项 1.直接插入排序: 代码实…

拥抱C++的深度和复杂性,挖掘更多可能 !——《C++20高级编程(第5版)》

,C难以掌握,但其广泛的功能使其成为游戏和商业软件应用程序中最常用的语言。即使是有经验的用户通常也不熟悉许多高级特性,但C20的发布提供了探索该语言全部功能的绝佳机会。《C20高级编程(第5版)》为C的必要内容提供了一个代码密集型、面向解…

(AtCoder Beginner Contest 325) ---- D - Printing Machine -- 题解

目录 D - Printing Machine: 题目大意: 思路解析: 代码实现: D - Printing Machine: 题目大意: 思路解析: 打印一次后,需要充电一微秒后才能再次打印就可以看作每微妙只能打印一…

【文献阅读】AlphaFold touted as next big thing for drug discovery — but is it?

今天来精读2023年10月发在《Nature》上的一篇新闻:AlphaFold touted as next big thing for drug discovery — but is it? (nature.com)https://www.nature.com/articles/d41586-023-02984-w Questions remain about whether the AI tool for predicting protein …

蓝桥杯基础练习详细讲解二(具体代码、解题思路、Python)

试题 基础练习 回文数 提交此题 评测记录 资源限制 内存限制:512.0MB C/C时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s 问题描述 1221是一个非常特殊的数,它从左边读和从右边读是一样的&#x…

C语言从入门到实战----C语言中内存函数的使用和模拟实现

目录 前言 1.memcpy 使用和模拟实现 2. memmove 使用和模拟实现 3. memset 函数的使用 4. memcmp 函数的使用 前言 在编程领域,内存管理是至关重要的一环,它确保了程序能够高效、稳定地运行。 C语言作为一门底层的编程语言,提供了一系…

Redis 教程系列之Redis 集群配置(十三)

1.Redis集群方案比较 主从模式 在软件的架构中,主从模式(Master-Slave)是使用较多的一种架构。主(Master)和从(Slave)分别部署在不同的服务器上,当主节点服务器写入数据时,同时也会将数据同步至从节点服务器,通常情况下,主节点负责写入数据,而从节点负责读取数据。…

橘子疾病检测4种YOLOV8

橘子检测YOLOV8,检测4种疾病,采用YOLOV8-NANO,训练得到PT模型转换成ONNX,最后OPENCV调用,支持C/PYTHON/ANDROID 橘子检测YOLOV8,检测4种疾病

2025汤家凤考研数学视频,基础网课百度网盘课程+PDF讲义资料

2025汤家凤大神及数学全程 docs.qq.com/doc/DTmtOa0Fzc0V3WElI 复制粘贴到浏览器,可以见所有的Ke 第一轮 夯实基础 1.阅读大纲考查要求,明确每章的学习目标; 2.按节学习数学理论基础知识,吃透书中例题; 3.学习每章…

【C语言】数组(一维、二维数组的简单介绍)

数组(Array) 数组概念 数组是一组相同数据类型元素的集合,属于一种简单的数据结构,从中可以得到三个有效信息 数组元素是同一数据类型的变量数组存放一个或者多个数据,但是数组元素个数不能为0数组中各元素可独立作为…

【Web APIs】DOM节点

目录 1.节点操作 1.1DOM节点 1.2查找节点 1.2.1父节点查找 1.2.2子节点查找 1.2.3兄弟节点查找 1.3增加节点 1.4克隆节点 1.5删除节点 2.时间对象 2.1实例化 2.2时间对象方法 2.3时间戳 3.重绘和回流 1.节点操作 1.1DOM节点 DOM节点:DOM树中的每一个…

CHAT~(持续更新)

CHAT(持续更新) 实现一个ChatGPT创建API设计页面布局业务操作技术架构 编码其他 实现一个ChatGPT 创建API 最简单也最需要信息的一步 继续往下做的前提 此处省略,想要获取接口创建方式联系 设计 页面布局 按照官网布局 业务操作 注册登…

绝地求生:PUBG七周年庆典开启!参与周年话题投稿赢丰厚奖励

为庆祝七周年,闲游盒PUBG官方准备了众多活动与奖励,一起在庆典中创造难忘的回忆吧!七周年庆典期间游玩PUBG,参与 #乐在7中鸡味无穷# 周年话题投稿,即有机会赢取魔力甜心萨莉套装 2奖励。 参与方式 在小黑盒PUBG社区中…

贪心算法相关题目

文章目录 1. 什么是贪心?2. 分发饼干3. 摆动序列4. 最大子数组和5. 买卖股票的最佳时机 II6. 跳跃游戏7. 跳跃游戏 II8.K 次取反后最大化的数组和9.加油站10.分发糖果11.柠檬水找零 1. 什么是贪心? 贪心的本质是选择每一阶段的局部最优,从而…

第1篇:Mysql数据库表结构导出字段到Excel(一个sheet中)

package com.xx.util;import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.sql.*; import java.io.*;public class DatabaseToExcel {public static void main(String[] args) throws Exception {// 数据库连接配置String u…

Less-1(sqlmap手工注入攻击)--sqli

第一步:判断他是什么sql注入? 1 报错 1 and 12 -- 错误结果(--表示注释符) 1 and 11 -- 正确结果 第二步:判断返回字段数 ?id1 order by 3-- 正确显示结果 ?id1 order by 4--当列数为4时开始报错,所以只有三列 注&#xf…

github的2FA问题

文章目录 问题描述方式一:chrome浏览器插件 问题描述 方式一:chrome浏览器插件 1、 第一步 安装插件:Authenticator 2、 第二步 打开github验证界面,并点击该插件

蓝桥杯-模拟-航班时间

题目 思路 去时到达外地的时间-去时离开本地的时间 时区差时飞行时间 回时到达本地的时间-回时离开外地的时间 -时区差时飞行时间 故二者加起来即可得到飞行时间 代码 # 去时到达外地的时间-去时离开本地的时间 时区差时飞行时间 # 回时到达本地的时间-回时离开外地的时间 -…

时间对比投资:衡量5天与10天六西格玛绿带培训的价值

六西格玛绿带培训专为希望提高其业务流程改进技能的专业人员设计。绿带培训通常涵盖六西格玛的基础知识、DMAIC(定义、测量、分析、改进、控制)方法论、以及各种质量管理工具和技巧。绿带受训者通常在他们的工作职责中负责领导小型项目或作为黑带项目团队的成员,下面…

小兴教你做平衡小车-蓝牙模块JDY-31介绍

文章目录 1 前言2 模块资料下载3 模块介绍3.1 模块特点3.2 模块相关指令介绍3.3 指令学习3.3.1 查看版本号3.3.2 软复位3.3.3 查看模块的波特率3.3.4 修改模块的波特率3.3.5 蓝牙配对密码查看3.3.6 修改蓝牙配对密码3.3.7 广播名查询3.3.8 广播名修改3.3.7 恢复出厂配置3.3.8 串…