TCP协议格式和特点

2023-11-06

文章目录

TCP :传输控制协议

1.协议格式:

在这里插入图片描述

  1. 16位源端端口-16位对端端口:描述通信两端

  2. 32位序号-32位确认序号:用于实现包序管理。

  3. 4位报头长度:描述tcp报头长度。4位表示最大数字15;以四字节为单位,所以TCp报头最小长度20字节,最大为15 * 4 = 60字节。

  4. 6位保留

  5. 6位标志位:

     	URG: 紧急指针是否有效
     	ACK: 确认应答
     	PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走
     	RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段
     	SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段
     	FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段 
    
  6. 16位窗口大小:用于实现滑动窗口机制–进行发送数据的流量控制。防止缓冲区溢出丢包。

  7. 16为校验和:校验数据一致性。

  8. 16位紧急指针:发送的带外数据的位置

  9. 0-40字节选项数据:存储一些可能需要的额外的信息。Mss…

  10. 应用数据

2.协议特性:

2.1 面向链接

面向链接:通信双方建立连接之后才能进行通信,—>确保通信双方都据有数据收发能力

TCP的链接管理:三次握手建立链接,四次挥手断开链接。
主要是为了确认通信双方都在线有数据收发能力。

2.1.1三次握手建立连接

客户端向服务端请求建立连接:
在这里插入图片描述

2.1.1四次挥手断开连接

在这里插入图片描述

相关问题和知识点:
1. 握手为啥三次,挥手是四次?

三次握收:双发都需要确定对方是否具有数据收发能力。两次不安全—只能确定服务端在线,客户端可能发送完SYN请求后就下线了。四次没必要—SYN和ACK都是报文中的标志位,分开发送没太大意义,直接将这两个标志位都置为1同时发送即可。
四次挥手:双方上层只有在不会发送数据的情况下才会发送FIN(FIN表示上层不再发送数据,但下层还能ACK确认回复)。收到FIN请求只能表示对方上层不再send发送数据,不代表对方不能再收数据了。因此有可能接收FIN请求的一方还会继续给对方发送数据,只有在上层调用了close或者shutdown关闭写才会主动给关闭方发FIN(不再发数据了).所以被动关闭方的FIN和ACK默认不一起发送。

2. 三次握手失败两端是如何处理的?

握手失败情况:
1.SYN请求丢失,客户端没得到确认回复,隔一段时间会重新发送SYN请求。多次发送失败会导致请求超时,连接失败。
2. 服务端发送的ACK+SYN信息丢失。客户端没收到SYN导致服务器没收到相应的的ACK回复,新建的套接字会重新发送ACK+SYN请求。若服务端发送ACK+SYN请求超时(服务端可能会觉得这是恶意攻击请求,只发起连接不回复,占用资源),给客户端发送RST重置连接报文,释放新建套接字的资源。
3. 客户端最后发送的ACK丢了。服务端等待超时,服务端发送RST,释放资源,从新建立连接。

3. SYN泛洪攻击是怎么回事?

黑客伪造ip不断向服务端发送SYN,但是不进行ACK回复,服务端新创建套接字会不断占用资源,直至枯竭崩溃。所以listen(sockfd,backlog)接口中有backlog参数–新建连接队列–队列满了就不会再新建套接字。处理方法:防火墙–同一ip频繁发送数据则拉黑名单。

4. 一台主机上出现了大量CLOSE_WAIT状态链接是什么原因?

CLOSE_WAIT状态是被动关闭方收到FIN请求并进行ACK回复之后进入到的状态。一旦自己发送了FIN(close操作后就会发送FIN)则会进入下一个LAST_ACK状态,因此有大量CLOSE_WAIT,意味着代码中可能没有对连接断开的套接字进行close操作。解决方案就是检查代码。

5. TIME_WAIT状态有什么作用?

在这里插入图片描述
TIME_WAIT状态是主动关闭方在收到对方FIN后,进行最后一次ACK回复后进入的状态。如果最后一次ACK丢失了,被动关闭方等待没收到ACK,则会重新发送FIN(只重传一次),所以TIME_WAIT状态就是等待这次可能重传的ACK。
TIME_WAIT实际上是为了保护新建套接字不会使用刚被释放的套接字的地址和端口,防止原先通信的数据对新连接造成的影响(本来需要发送到原先套接字的重传FIN发送送到了新套接字的通信会话中)。
TIME_WAIT会等待两个MSL(最大报文生存周期)时间---->最后重传FIN和ACK的时间 X 2,确保本次通信的数据都消失在网络中,不会对新的连接造成影响。
TIME_WAIT实际上更多是为了保护客户端,客户端通常不主动绑定地址信息,交给系统分配;而服务端通信通常需要绑定相同的地址信息,重启之后地址信息不变。
在这里插入图片描述

6. 一台主机上出现大量TIME_WAIT链接,什么原因,怎么解决?

TIME_WAIT是主动关闭方最后一次发送ACK产生的。
出现大量TIME_WAIT则是因为大量主动关闭套接字,常见于爬虫主机。
解决方案:将TIME_WAIT等待时间设置更短一些。
或:设置套接字选项,开启地址复用,常见于服务端。
int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
level:SOL_SOCKET
optname:SO_REUSEADDR

7. TCP的保活机制(心跳探测)

默认情况:通信双方7200s没有通信,则服务端每隔75s会向客户端发送一个保活探测数据包,要求客户端进行回复,连续9次没有进行回复则认为连接断开。
可以设置保活时间和次数。
连接断开在后程序在上层的表现:recv返回0;send会触发SIGPIPE异常—>会导致进程异常退出,可自定义SICPIPE信号的处理方式。
在这里插入图片描述

2.2 可靠传输

2.2.1 安全有序传输(保证数据可靠到达对端并且有序进行交付)

面向链接(前提):首先确保双方都具有数据收发能力

1. 确认应答机制

实现丢包检测功能,接收方针对接收的每一条数据都应该进行确认回复。
发送方收到确认回复认为传输成功,否则认为数据丢包。

2. 超时重传机制

发送方等待超时没有得到确认回复,则会对数据包重新传输。超时等待时长会随着网络环境的不同, 是有差异的.如果超时时间设的太长, 会影响整体的重传效率;如果超时时间设的太短, 有可能会频繁发送重复的包;

3. 协议字段中的序号(th_seq)和确认序号(th_ack)进行包序管理,实现有序交付

利用==协议字段中的序号(th_seq)和确认序号(th_ack)==进行包序管理,实现有序交付。
在这里插入图片描述
举个例子感受一下序号(th_seq)和确认序号(th_ack)的作用,下图中seq为其实序号,ack表示确认序号。
在这里插入图片描述

4. 协议字段中的校验和校验数据一致性。

数据不一致则丢弃,丢弃则无针对此数据的确认回复,对方收不到确认回复则重传此数据;也可直接发送重传请求。

2.2.2 避免没必要的丢包

丢包情况:

  1. 发送方发送数据过多,接收方来不及处理,缓冲区溢出之后所产生的丢包。
    2.>传输起始或者过程中网络突然变差所导致的大量丢包。
1. 滑动窗口机制

依赖于协议字段中的窗口大小字段实现,避免发送方发送数据过多,接收方来不及处理,缓冲区溢出之后所产生的丢包。
原理:接收方接收数据之后就会进行确认应答,这时候会通过窗口大小字段告诉对方最多再给自己发送多少数据。窗口大小不能大于接收缓冲区剩余空间大小。
实现:通信双方都会维护一个发送窗口和接收窗口。
图画不动了,参考文章:网络 滑动窗口机制,这个里面有比较图解,过程较详细。

相关概念:

MSS:最大数据段大小,表示一个TCP报文中数据的最大大小。

相关协议:

停等协议:发送数据之后,收到确认回复才会发送下一条。适合网络环境差的场景。
回退n步协议:那一条数据丢失,则从丢失的数据包开始整体重传。
选择重传协议:哪条丢失重传哪条。适用于网络环境较好的场景。
2. 拥塞窗口机制

拥塞窗口机制:解决网络突然变差产生大量丢包的问题。
原理:发送方维护了一个拥塞窗口,用于限制当前所能发送的数据量。拥塞窗口大小是一种慢启动快增长(指数上涨,阈值为窗口大小)的形式进行传输控制。防止突然网络变差,导致大量丢包。每次丢包都会进行一次网络状况探测的过程。

2.2.3 提高一些传输性能

tcp为了实现可靠传输,牺牲了传输性能,而在传输过程中,有些性能上的损失是没有必要的。

1. 确认序号

确认序号标识序号之前的数据都已经收到了,为了避免因为确认应答丢失导致的重传。

2. 快速重传协议

在传输过程中,若接收方接收到的数据并非是接收窗口后沿数据,则有理由认为前边发送的数据丢失了,这时候每收到一条数据就会发送一条后沿数据的重传请求,一旦发送方连续收到三条(三条是为了避免数据延迟到达的情况)相同重传请求,则直接对这条数据(确认序号的数据)进行重传。丢包后不用完全等待超时重传,节省时间。

3. 捎带应答机制:

接收方对接收到的每一条数据都需要进行确认回复,然而确认回复最主要的信息就是确认序号,因此每一条确认回复都是一个tcp传输,至少是一个空报头(没有实际数据)的传输。如果收到数据后刚好要给对方发送数据,则将及即将要发送的数据和确认回复放到一起进行发送(在要发送的数据报头中加入确认序号)。

4. 延迟应答机制

接收方对接收到的每一条数据都需要进行确认回复,其中包含有当前窗口大小字段,如果立即进行回复,窗口大概率是不断减小的,因此延迟进行确认回复,有可能上层将数据取出,维持窗口大小。通过这种方式保证传输吞吐量不会降低。

5. 延迟发送机制

tcp传输过程中,如果对每次send的数据直接封装报头进行发送,若发送的数据比较小,但是次数较多,则io次数比较多,效率低。因此延迟发送,将数据在发送缓冲区中先堆积起来,再合适的时候一次性发送,减少了io次数,提高效率。
nagle算法–通过套接字选项设置(默认是开启的)

2.3 面向字节流传输

面向字节流传输:可靠的,有序的,双向的,基于连接的,以字节为单位的传输方式。传输时,并不限制上层(send \ recv)发送或者接收的数据大小。tcp延迟发送数据在缓冲区中积攒,基于mss取出合适大小数据进行发送。
优势:相对于面向数据报来说,传输更加灵活。
缺陷:产生粘包问题—将多条数据当作一条数据处理。
产生粘包的原因:tcp不会对数据进行边界处理。
解决方案:程序员需要在应用层进行数据的边界管理。可用特殊字符作为间隔(需要考虑特殊字符转译);使用TLV格式数据(在应用层头部加入数据长度);数据定长----提前约定会定长的数据,但是数据太短需要进行补全;

3 对应用层编程影响

  1. 连接断开:recv返回0,send触发异常。
    recv一旦返回0,就要考虑文件描述符的回收关闭
    Send因为会触发一次导致进程退出,若不想退出进程需要自定义信号处理。
  2. tcp传输存在粘包问题,需要在应用层进行数据边界管理。udp整条交付,无粘包问题。
问题:tcp和udp协议的区别?

实现上的区别:协议格式,协议字段不一样。
特性上的区别:TCp是面向连接的可靠的字节流传输方式。udp是无连接不可靠面向数据报的传输方式。udp支持广播,tcp不支持。
应用场景上的区别:UDP适用于实时性高于安全性的场景,tcp用于传输安全性高于实时性的场景。

tcp如何实现可靠传输
  1. 确认应答机制
  2. 超时重传机制
  3. 协议字段中的序号(th_seq)和确认序号(th_ack)进行包序管理,实现有序交付
  4. 协议字段中的校验和校验数据一致性。
udp如何实现可靠传输

ud协议本身没有实现可靠传输,需要在应用层手动实现类似tcp的可靠传输机制:确认应答机制,超时重传机制,包序管理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TCP协议格式和特点 的相关文章

  • Linux 使用 boost asio 拒绝套接字绑定权限

    我在绑定套接字时遇到问题 并且以用户身份运行程序时权限被拒绝 这行代码会产生错误 acceptor new boost asio ip tcp acceptor io boost asio ip tcp endpoint boost asi
  • 如何在不使用 IDE 的情况下在 Linux 上运行 Java 项目

    我是 Java 新手 基本上 我开发了一个java项目 其中包含Eclipse中的多个Java包 该项目在我安装了 redhat Linux 的桌面上运行正常 然而 我需要在一个更强大的没有安装X11的Linux服务器 redhat ent
  • 使用套接字和 AsyncTask 强制关闭

    堆栈的人们大家好 请参阅下面我的班级代码和我的 LogCat 尝试连接时我受到强力关闭 如果有人能帮助我找出原因 我将不胜感激 基本上代码的作用是 从意图中获取 IP 地址 连接到端口 32 的 IP 然后发送一个命令 等待响应并发送另一个
  • ioctl 命令的用户权限检查

    我正在实现 char 驱动程序 Linux 并且我的驱动程序中有某些 IOCTL 命令仅需要由 ADMIN 执行 我的问题是如何在 ioctl 命令实现下检查用户权限并限制非特权用户访问 IOCTL 您可以使用bool capable in
  • 批量删除文件名中包含 BASH 中特殊字符的子字符串

    我的目录中有一个文件列表 opencv calib3d so2410 so opencv contrib so2410 so opencv core so2410 so opencv features2d so2410 so opencv
  • 仅使用containerd(不使用Docker)修剪容器镜像

    如果我刚刚containerd安装在 Linux 系统上 即 Docker 是not安装 如何删除未使用的容器映像以节省磁盘空间 Docker 就是这么方便docker system prune https docs docker com
  • 为什么 Linux 没有 DirectX API?

    在考虑现代显卡的 Windows 系统上 DirectX API 的驱动程序端实现时 我想知道为什么此实现在非 Windows 系统 尤其是 Linux 上不可用 由于明显缺乏此功能 我只能假设有一个我无视的充分理由 但在我的原始理解中 我
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 就分页分段内存而言的程序寿命

    我对 x86 Linux 机器中的分段和分页过程有一个令人困惑的概念 如果有人能澄清从开始到结束所涉及的所有步骤 我们将很高兴 x86 使用分页分段内存技术进行内存管理 任何人都可以解释一下从可执行的 elf 格式文件从硬盘加载到主内存到它
  • 如何在 Ubuntu 中创建公共 HTML 文件夹?

    简单的问题 但由于某种原因我无法在谷歌上找到确切的答案 我在 Slicehost 上安装了全新的 Ubuntu 并且想在我的主目录中为包含一堆静态 HTML 文件的简单网站创建一个公共目录 我该怎么做呢 只是打字的问题吗mkdir publ
  • 如何在linux中以编程方式获取dir的大小?

    我想通过 C 程序获取 linux 中特定目录的确切大小 我尝试使用 statfs path struct statfs 但它没有给出确切的大小 我也尝试过 stat 但它返回任何目录的大小为 4096 请建议我如何获取 dir 的确切大小
  • 尽管 if 语句,Visual Studio 仍尝试包含 Linux 标头

    我正在尝试创建一个强大的头文件 无需更改即可在 Windows 和 Linux 上进行编译 为此 我的包含内容中有一个 if 语句 如下所示 if defined WINDOWS include
  • 使用非规范地址检索内存数据会导致 SIGSEGV 而不是 SIGBUS

    我无法使用以下汇编代码产生 总线错误 这里我使用的内存地址不是合法的 规范地址 那么 我怎样才能触发该错误呢 我在带有 NASM 2 14 02 的 Ubuntu 20 04 LTS 下运行这段代码 但它会导致负载出现 SIGSEGV 分段
  • 添加文件时运行 shell 命令

    我的 Linux 机器上有一个名为 images 的文件夹 该文件夹连接到一个网站 该网站的管理员可以向该网站添加图片 但是 当添加图片时 我想要一个命令来运行调整目录中所有图片的大小 简而言之 我想知道当新文件添加到特定位置时如何使服务器
  • 如何获取 (Linux) 机器的 IP 地址?

    这个问题和之前问的几乎一样如何获取本地计算机的IP地址 https stackoverflow com questions 122208 get the ip address of local computer 问题 但是我需要找到一个的I
  • 为什么 fopen("any_path_name",'r') 不给出 NULL 作为返回值?

    在调试一些代码时 我得到如下内容 include
  • 如何让R使用所有处理器?

    我有一台运行 Windows XP 的四核笔记本电脑 但查看任务管理器 R 似乎一次只使用一个处理器 如何让 R 使用全部四个处理器并加速我的 R 程序 我有一个基本系统 我使用它在 for 循环上并行化我的程序 一旦您了解需要做什么 此方
  • Bash - 在与当前终端分开的另一个终端中启动命令的新实例

    我有一个简单的 bash 脚本 test sh 设置如下 bin bash args if args 0 check capture then watch n 1 ls lag home user capture0 watch n 1 ls
  • 内核的panic()函数是否完全冻结所有其他进程?

    我想确认内核的panic 功能和其他类似kernel halt and machine halt 一旦触发 保证机器完全冻结 那么 所有的内核和用户进程都被冻结了吗 是panic 可以被调度程序中断吗 中断处理程序仍然可以执行吗 用例 如果
  • 静态方法的 Java 内存模型

    我来自操作系统和 C 语言背景 在代码编译时 世界很简单 需要处理和理解堆栈 堆文本部分等 当我开始学习 Java 时 我确实了解 JVM 和垃圾收集器 我对静态方法感到很有趣 根据我的理解 类的所有实例都会在堆中创建 然后被清理 但是 对

随机推荐

  • 关于int *a; int &a; int & *a; int * &a

    上述的四条语句 前面两个很好理解 而后面两个 大部分C 初学者都会比较困惑 今天我也是查阅了一些资料以后才恍然大悟 下面具体来说明一下 int i int a i 这里a是一个指针 它指向变量i int b i 这里b是一个引用 它是变量i
  • linux搭建 PXE 远程安装服务器及无人值守

    注意 新建虚拟机 cpu 2个 内存不能低于4g 内存不低于20g 否则会失败 步骤 root localhost systemctl stop firewalld service 关闭防火墙 root localhost setenfor
  • 修改mysql的时间/时区

    应用背景 有时候会发现数据库存储的时间与当前所在地区的时间不同 尤其是涉及到全球业务的时候 如果有些程序是根据时间判断来进行后面的逻辑 往db中insert数据发现时间不对 尤其是新DB 可能是mysql设置不对 这时由于时区问题影响存入的
  • 【热门框架】Maven怎样进行版本管理?有哪些需要注意事项?

    Maven的版本管理是指对项目的依赖库和发布版本进行管理 可以通过配置pom xml文件来实现 下面是Maven进行版本管理的一些要点和注意事项 依赖库版本管理 在pom xml文件中 可以通过dependencyManagement元素来
  • java 内存分配策略

    1 对象优先在新生代Eden区中进行分配 当Eden区没有足够空间进行分配时 虚拟机进行一次Minor GC 2 大对象直接进入老年代 所谓大对象就是需要大量连续内存空间的java对象 最典型的大对象就是很长的字符串以及数组 3 长期存活的
  • 汇编指令:左移RL和RLC区别

    转载 https www cnblogs com zhangfan2014 p 4583947 html 汇编指令RL和RLC区别 RL是左移指令 参加左移的是8个位 RLC是带进位位的左移 参加左移的共有9个位 设A 0100 0001
  • 跳点搜索算法 (JPS算法) && 效率优化(摘录)

    摘自 腾讯游戏开发精粹 摘录一次加深记忆方便查找 并未盈利 如有侵权 联系作者删除 如感兴趣 请购买原书支持 谢谢配合 JPS主体思路 表现上 JSP算法比A 快很多 实际上快到哪里了 我们大概了解一下 A 会遍历每一个附近的点 然后把符合
  • 【RTT驱动框架分析07】- adc驱动框架分析+adc中断唤醒adc驱动

    ADC adc应用开发 访问 ADC 设备 应用程序通过 RT Thread 提供的 ADC 设备管理接口来访问 ADC 硬件 相关接口如下所示 函数 描述 rt device find 根据 ADC 设备名称查找设备获取设备句柄 rt a
  • xshell5激活

    xshell5产品秘钥 150105 116578 999990 xftp5产品秘钥 150105 116578 999990 xshell5产品秘钥 101210 450789 147200 xftp5产品秘钥 101210 450789
  • 突发奇想-基于重力感应的人体姿态控制型无人机

    基于重力感应的人体姿态控制型无人机 初级阶段目标 短距离重力感应控制 遥控器重力模块直接连接控制 手持遥控器不平稳问题 最终目标 控制系统迁移至人体 进行直接姿态操作 重力感应 压电效应 当晶体受到固定方向外力作用时 内部产生电极化现象 同
  • [YOLO专题-28]:YOLO V5 代码管理 - 如何与官网协同开发自己的项目代码

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 122519479 目录 前言
  • C++数组练习题(一)

    在刚开始学习c 的时候刷了很多基础题 这些基础题比较适合初学C 的码友 所以在学完就立即进行了整理 一是为了让初学C 的码友有所参考 二也是为了复习一下所学过知识 但因为当时在整理时 时间有点紧促 可能会出现一些小错误 于是利用五一假期对之
  • Tensorflow:数据特征值的自变量为离散值

    import pandas as pd from sklearn utils import shuffle dataSet pd read csv input mushrooms csv mapPto1Eto0 p 1 e 0 dataSe
  • vite详解

    vite详解 卖菜的小白的博客 CSDN博客 vite 一 认识vite webpack是目前整个前端使用最多的构建工具 但是除了webpack之后也存在其他一些构建工具 比如说rollup parcel gulp vite等等 vite的
  • Twitter开发者账号申请流程

    文章转自 https www jianshu com p cfb741dd52dd 这篇文章主要介绍在最新的推特开发者平台申请账号的流程 首先需要有一个推特账号 其次该推特账号必须是首次申请 因为推特开发者一个账号只能申请一次 申请后被拒绝
  • 【Streamlit学习心得】个人项目实战,并部署在Streamlit Cloud,生成一个公网url随时访问

    Streamlit学习心得 个人项目实战 并部署在Streamlit Cloud 生成一个公网url随时访问 目录 Streamlit学习心得 个人项目实战 并部署在Streamlit Cloud 生成一个公网url随时访问 前言 一 全局
  • TCP的连接

    一 套接字 1 每一条TCP连接有两个端点 TCP连接的端点叫做套接字 socket 或插口 2 套接字 socket IP地址 端口 例如 套接字 socket 192 168 170 1 80 二 TCP连接 1 建立连接时的三次 握手
  • GPU RayTracing

    参考自 https github com Ubpa ToyRTX 使用三种Texture 记录场景数据 1 SceneData 2 MatData 3 PackData 数据 https docs qq com sheet DQ2FqdE1
  • 秋招准备之——MySQL复习

    秋招复习笔记系列目录 不断更新中 1 数据结构全系列 2 计算机网络知识整理 一 3 计算机网络知识整理 二 4 Java虚拟机知识整理 5 计算机操作系统 6 深入理解HashMap 7 深入理解ConcurrentHashMap 8 M
  • TCP协议格式和特点

    文章目录 1 协议格式 2 协议特性 2 1 面向链接 2 1 1三次握手建立连接 2 1 1四次挥手断开连接 相关问题和知识点 1 握手为啥三次 挥手是四次 2 三次握手失败两端是如何处理的 3 SYN泛洪攻击是怎么回事 4 一台主机上出