TCP协议

2023-05-16

        TCP(Transmission Control Protocol)是面向连接的可靠的通讯协议。TCP需要经过三次握手建立连接,并在断开时通过四次挥手释放连接。TCP通过应答确认、超时重传(RTO)、往返时延(RTT)、数据排序、流量控制、全双工通讯的机制和特性,保证连接的可靠性。

可靠传输

        超时重传:RTO,Retransmission TimeOut。TCP对收到的每一帧数据都需要给予应答,如果发送端超过一定时间没有收到来自对端的应答,则重传该帧数据。超时的时长根据网络情况动态调整,网络较好时,超时时间较短。这里是根据数据包往返时延(RTT,round-trip time,数据包从发送端发送出去到接收到这个包的回复时长)进行调整。通过算法和公式平滑RTT值后,最终确定重传超时值。

        数据排序:IP层进行数据传输时,是不能保证数据包按照发送的顺序达到目的机器。当IP将把它们传送到TCP层后,TCP将包排序并进行错误检查。TCP数据包中包括序号和确认,所以未按照顺序收到的包可以被排序,而损坏的包可以被重传。

        流量控制:TCP采用一种称为“滑动窗口”的方式进行流量控制,所谓窗口实际表示接收能力,用以限制发送方的发送速度。当接收方处理能力强时,窗口增大,表示可以接收更多的数据,否则窗口减少。由此来平衡发送和处理数据的速度。

        全双工:即通信的双方可以同时发送和接收数据。(半双工:发送和接收不能同时进行。单工:只能一端往一端发送)。TCP是全双工的通讯方式。

三次握手

        三次握手就是,TCP建立连接时,需要在客户端和服务端之前总共发送三个包来确认连接。

        第一次握手:客户端设置SYN标志位为1,产生一个随机seq=J,将这两个值发送给服务端。Client进入SYN_SENT状态,等待Server端确认。

        第二次握手:服务端收到并解析数据包,得到SYN=1,知道此客户端在请建立连接。服务端设置SYN和ACK标志都为1,将客户端提供的随机值+1,即ack=J+1,产生一个随机值seq=K。服务端将包含以上信息的包发送给客户端端。服务端进入SYN_RCVD状态,并等待客户端再次确认。

        第三次握手:客户端收到服务端回复数据包,检查ACK是否为1,以及ack的值是否为J+1。检查通过,将服务端的随机值+1,即ack=K+1,同时设置ACK为1。将包含这些信息的数据包再次发送给服务端端。客户端进入ESTABLISHED状态。服务端收到数据后,检查ack是否为K+1,以及ACK是否为1。检查通过,进入ESTABLISHED状态。至此完成三次握手,连接建立,客户端和服务端可以进行数据传输。

需要三次握手的原因

        TCP是一种全双工的通讯,即客户端和服务端都可以同时进行收发数据。第一次握手确认了客户端发数据正常;第二次握手确认客户端收数据正常和服务端发数据正常;第三次确认了服务端收数据正常。因此,“三次”是通讯双方能够确认彼此都能够正常收发数据所需要的最小次数

四次挥手

        四次挥手,就是断开连接时,需要客户端和服务端总共发送4个包以确认断开连接。 

        第一次挥手,客户端请求关闭(此时客户端称为“执行主动关闭”),将FIN标志置为1,生成随机序列号seq = U。将数据包发送给服务端。客户端进入FIN-WAIT-1状态(等待关闭状态)。

        第二次挥手,服务端接收到消息,解析出FIN=1,得知客户端请求断开连接(服务端此时称为“执行被动关闭”)。设置ACK标志为1,回复序列号+1,即ack_seq=U+1,生成随机序列号seq=V。将这些信息发送给客户端。此时服务端进入CLOSE_WAIT状态(半关闭状态)。

        客户端收到服务端消息,进入FIN-WAIT-2(终止关闭2)状态。此时表示客户端没有消息要发送给服务端。而服务端可能还有数据要发给客户端。

        第三次挥手,当服务端确定也没有数据要发送给客户端后。将发送请求终止报文。设置FIN标志为1,并生成随机序列号seq=W。请求关闭连接。此时服务端进入LAST_ACK(等待确认)状态。

        第四次挥手,客户端收到服务端请求关闭请求。设置ACK标志为1,恢复服务端序列号+1,即ack_seq=W+1。发送给服务端。此时客户端进入TIME_WAIT状态。等待一段时间后客户端关闭连接,进入CLOSE状态。

        服务端收到客户端回复确认消息,进行关闭连接,进入CLOSE状态。

TIME_WAIT状态

        主动关闭端进入TIME-WAIT状态,此时TCP连接还没有释放,需要等待2*MSL的时间(MSL是最长报文寿命,表示一个报文能够在网络中存活的最长时间。这个值一般设置在30s到1min之间)才进行关闭连接动作。

        TIME-WAIT状态存在的意义是保证可靠的终止TCP连接和迟到的TCP报文有足够的时间被识别和丢弃。

        在第四次挥手的时候,客户端收到服务器连接释放的请求,需要再发出确认的报文。如果最后这个报文丢失,服务端没有收到就会再次发出释放的请求,客户端收到后要再次应答。如果,客户端是直接关闭连接,这种情况下,将无法再收到服务端再次请求释放的报文和进行应答。因此,客户端需要等待给服务端足够的接收到报文的时间,这样才能可靠的终止连接。

        另外,一个TCP端口一次只能被一个应用打开。当一个应用占用一个TCP端口时,其他的应用将无法占用该端口。如果在第四次挥手后,客户端直接释放了端口,则其他应用可以进行使用。此时如果网络上还有数据要发送给第一个应用程序,那么数据将会被后来的应用程序错误的接收。因此,需要TIME_WAIT的时间,让迟来的TCP报文有足够的时间被丢弃。从而避免由于端口复用而导致数据被错误的传递。

SYN洪泛攻击

        SYN洪泛攻击是面向TCP连接的主要网络攻击手段。攻击者伪造IP地址向服务器发起握手请求,当服务器进行响应(发送第二次握手请求)时,会处于等待客户端响应的状态。由于IP地址是伪造的,因此永远不能得到第二次握手的响应。攻击者大量发起请求,让服务器大量的资源用于等待握手连接,导致服务器资源耗尽无法处理正常的连接请求。

        应对SYN洪泛攻击主要有如下的方案:

        无效连接监视释放:不停监视所有的连接,当达到一定阈值时拆除这些连接,从而释放系统资源。缺点是,这种方法对于所有的连接一视同仁,不管是正常的还是攻击的。

        延缓TCB分配方法:一般的做完第一次握手之后,服务器就需要为该请求分配一个TCB(连接控制资源),通常这个资源需要200多个字节。延迟TCB的分配,当正常连接建立起来后再分配TCB则可以有效地减轻服务器资源的消耗。

        使用防火墙(推荐):防火墙在确认了连接的有效性后,才向内部的服务器(Listener)发起SYN请求。

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

TCP协议 的相关文章

  • 如何在Linux中打开端口[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我已经安装了 Web 应用程序 该应用程序在 RHEL centOS 上的端口 8080 上运行 我只能通过命令行访问该机器 我尝试从我的
  • 触发“对等方重置连接”

    我想测试当发生 对等方重置连接 错误时我们的应用程序 嵌入式 ftp 服务器 中发生的日志记录 这个帖子 https stackoverflow com questions 1434451 connection reset by peer很
  • 使用 boost 异步发送和接收自定义数据包?

    我正在尝试使用 boost 异步发送和接收自定义数据包 根据我当前的实现 我有一些问题 tcpclient cpp include tcpclient h include
  • 如果其中一台机器死机,TCP 连接如何终止?

    如果两个主机 A 和 B 之间建立了 TCP 连接 假设主机 A 已向主机 B 发送了 5 个八位字节 然后主机 B 崩溃了 由于未知原因 主机 A 将等待确认 但如果没有收到确认 将重新发送八位字节并减小发送者窗口大小 这将重复几次 直到
  • 中断 Select 以添加另一个要在 Python 中监视的套接字

    我正在 Windows XP 应用程序中使用 TCP 实现点对点 IPC 我正在使用select and socketPython 2 6 6 中的模块 我有三个 TCP 线程 一个读取线程通常会阻塞select 一个通常等待事件的写入线程
  • 如何在Linux内核源代码中打印IP地址或MAC地址

    我必须通过修改 Linux 内核源代码来稍微改变 TCP 拥塞控制算法 但为了检查结果是否正确 我需要记录 MAC 或 IP 地址信息 我使用 PRINTK 函数来打印内核消息 但我感觉很难打印出主机的MAC IP地址 printk pM
  • 建立 TCP 连接边界的正确方法

    我的问题是关于如何正确处理使用 tcp 连接接收的数据 事实上 通过建立 tcp 连接 创建了一个流 假设我想发送一条有开头和结尾的消息 由于数据在流中流动而没有指定任何边界 我如何识别消息的开始和结束 我想在消息的开头和结尾处放置一些特殊
  • 当 TCP 序列号到达而不是预期时会发生什么情况?

    我正在编写一个程序 使用 libpcap 捕获数据包并重新组装 TCP 流 我的程序只是监视流量 因此我无法控制数据包的接收和发送 我的程序忽略所有非 TCP IP 流量 我根据 ISN 计算下一个预期序列号 然后计算连续的 SEQ 号 我
  • Apache HttpClient TCP Keep-Alive(套接字保持活动)

    我的 http 请求需要太多时间才能被服务器处理 大约 5 分钟 由于连接闲置 5 分钟 代理服务器将关闭连接 我正在尝试在 Apache DefaultHttpClient 中使用 TCP Keep Alive 来使连接长时间处于活动状态
  • 通过 TCP/.NET SSLStream 发送文件很慢/无法正常工作

    我正在编写一个与 SSL 配合使用的服务器 客户端应用程序 通过SSLStream 它必须做很多事情 不仅仅是文件接收 发送 目前 它的工作原理是 只有一个连接 我总是使用从客户端 服务器发送数据SSLStream WriteLine 并使
  • 了解 netty 通道缓冲区和水印

    我正在尝试了解网络缓冲区和水印 作为一个测试用例 我有一个 netty 服务器 它向客户端写入数据 客户端被阻止 基本上每次读取之间有 10 秒的睡眠时间 在正常 I O 下 如果接收方被阻塞 TCP 发送方将受到限制 由于流量控制 发送速
  • Java Servlet 中限制 HTTP 请求

    在 java servlet 中 如何根据客户端的 IP 地址限制来自用户的 http 请求 我不想每秒处理来自特定源 IP 地址的超过 X 个请求 其中 X 是可配置的并且具有 0 1 中的实际值 10 范围 从 10 秒内 1 个请求到
  • Docker 容器是否有自己的 TCP/IP 堆栈?

    我试图了解来自连接到主机的线路并定向到 Docker 容器内的应用程序的网络数据包在幕后发生了什么 如果它是一个经典的 VM 我知道到达主机的数据包将由虚拟机管理程序 例如 VMware VBox 等 传输到 VM 的虚拟 NIC 并从那里
  • iPhone 上的 TCP 打洞

    我已经阅读了一些内容 虽然我是 iPhone 网络的新手 但我想知道 TCP 打孔是否可以通过 NAT 连接两台 iPhone 我还阅读了一些有关 uPnP 和发夹的有用内容 但我根本不熟悉这些内容 所以如果有人对这是否可能有任何想法 我的
  • TCP 中推送标志和紧急标志之间的区别

    我试图理解带有标志的 TCP 段之间的区别PSH和旗帜URG 我阅读了 RFC 但仍然无法获取它 其中一个在将数据发送到进程之前是否缓冲数据 而另一个则没有 它们是两种截然不同的机制 PSH 和 PUSH 函数 当您发送数据时 您的TCP缓
  • Silverlight 套接字:模仿框架 Bind、Listen 和 Accept 方法?

    我有这个 NET Framework C 类 它实际上充当 TCP 连接的包装器Socket http msdn microsoft com en us library attbb8f5 aspxSystem Net Sockets 命名空
  • TCL类C10K事件服务器开发进展如何?

    TCL 是一种很好的简单编程语言 但似乎没有得到认可和 或尊重它deserves http antirez com articoli tclmisunderstood html 我 1995 年在大学时就学过它 但很快就忘记了 直到最近才再
  • SO_REUSEPORT 可以在 Unix 域套接字上使用吗?

    Linux 内核 gt 3 9 允许通过设置在内核负载平衡的进程之间共享套接字SO REUSEPORT http lwn net Articles 542629 http lwn net Articles 542629 这如何用于类型的套接
  • 在本地主机上使用相同的 IP 和端口创建套接字

    我在 Linux 上看到奇怪的行为 我看到远程端和本地端都显示相同的 IP 和端口组合 以下是 netstat 输出 netstat anp 网络统计grep 6102 tcp 0 0 139 185 44 123 61020 0 0 0
  • 伪TCP通道

    什么是伪 TCP 通道以及如何实现 伪 TCP 是一种协议 它实现了 TCP 的一些思想 通过不可靠的基于数据包的接口提供可靠的数据流 例如 如果您只能访问 UDP 但想要 一种可靠的方式来传递数据 则可以使用此方法 您可以在这里找到示例代

随机推荐

  • Git - - subtree与submodule

    https www cnblogs com anliven p 13681894 html 目录 1 仓库共用 子仓库 子项目 2 submodule 与 subtree 对比 2 1 git submodule2 2 git subtre
  • 一起自学SLAM算法:第9章-视觉SLAM系统

    连载文章 xff0c 长期更新 xff0c 欢迎关注 xff1a 写在前面 第1章 ROS入门必备知识 第2章 C 43 43 编程范式 第3章 OpenCV图像处理 第4章 机器人传感器 第5章 机器人主机 第6章 机器人底盘 第7章 S
  • 一起自学SLAM算法:第10章-其他SLAM系统

    连载文章 xff0c 长期更新 xff0c 欢迎关注 xff1a 写在前面 第1章 ROS入门必备知识 第2章 C 43 43 编程范式 第3章 OpenCV图像处理 第4章 机器人传感器 第5章 机器人主机 第6章 机器人底盘 第7章 S
  • 一起自学SLAM算法:第11章-自主导航中的数学基础

    连载文章 xff0c 长期更新 xff0c 欢迎关注 xff1a 写在前面 第1章 ROS入门必备知识 第2章 C 43 43 编程范式 第3章 OpenCV图像处理 第4章 机器人传感器 第5章 机器人主机 第6章 机器人底盘 第7章 S
  • 一起自学SLAM算法:11.5 强化学习与自主导航

    连载文章 xff0c 长期更新 xff0c 欢迎关注 xff1a 写在前面 第1章 ROS入门必备知识 第2章 C 43 43 编程范式 第3章 OpenCV图像处理 第4章 机器人传感器 第5章 机器人主机 第6章 机器人底盘 第7章 S
  • 一起自学SLAM算法:第12章-典型自主导航系统

    连载文章 xff0c 长期更新 xff0c 欢迎关注 xff1a 写在前面 第1章 ROS入门必备知识 第2章 C 43 43 编程范式 第3章 OpenCV图像处理 第4章 机器人传感器 第5章 机器人主机 第6章 机器人底盘 第7章 S
  • 一起自学SLAM算法:第13章-机器人SLAM导航综合实战

    连载文章 xff0c 长期更新 xff0c 欢迎关注 xff1a 写在前面 第1章 ROS入门必备知识 第2章 C 43 43 编程范式 第3章 OpenCV图像处理 第4章 机器人传感器 第5章 机器人主机 第6章 机器人底盘 第7章 S
  • 一起自学SLAM算法:13.4 基于自主导航的应用

    连载文章 xff0c 长期更新 xff0c 欢迎关注 xff1a 写在前面 第1章 ROS入门必备知识 第2章 C 43 43 编程范式 第3章 OpenCV图像处理 第4章 机器人传感器 第5章 机器人主机 第6章 机器人底盘 第7章 S
  • 在ubuntu18.04中安装opencv_contrib-3.2.0闭坑记录

    由于最近要在OpenCV3中使用SIFT和SURF特征提取 xff0c 而自从OpenCV2升级到OpenCV3版本后 xff0c SIFT SURF等这些算法都被移出opencv默认项目库 xff0c 而被放到叫opencv contri
  • 在ROS中使用超声波(sonar)导航避障

    1 下载sonar layer的代码 https github com DLu navigation layers 实际只需要其中的range sensor layer放到工作空间catkin make 实验时放置于src中 xff0c 可
  • rtabmap更加适合视觉SLAM建图和导航

    slam问题目前主要集中在如何建立一个好的地图 xff0c 至于后续如何使用地图这部分工作研究的不多 xff0c 不过我个人恰好在做这部分工作所以答一下个人见解 首先 xff0c 有一张好的地图 xff0c 是导航或地图语义分析等应用的前提
  • Git应用详解第十讲:Git子库:submodule与subtree

    https www cnblogs com AhuntSun blog p 12736934 html 前言 前情提要 xff1a Git应用详解第九讲 xff1a Git cherry pick与Git rebase 一个中大型项目往往会
  • 单片机串口通信程序

    本文总结了两种比较简单的关于串口发送接收的程序 xff0c 以下是步骤 xff1a 定义数据 xff1a unsigned char idata URX 10 61 0 串口接收数组 unsigned char idata URX Num
  • Linux当中的压栈和出栈指令以及跳转指令详细教程

    1 跳压栈出栈指令 xff1a 我们通常会在 A 函数中调用 B 函数 xff0c 当 B 函数执行完以后再回到 A 函数继续执行 要想 再跳回 A 函数以后代码能够接着正常运行 xff0c 那就必须在跳到 B 函数之前将当前处理器状态保存
  • MySQL5.7版本在Ubuntu(WSL环境)系统安装

    课程中配置的WSL环境是最新的Ubuntu22 04版本 xff0c 这个版本的软件商店内置的MySQL是8 0版本 所以我们需要额外的步骤才可以安装5 7版本的MySQL 安装操作需root权限 xff0c 你可以 xff1a 通过 su
  • 动态库静态库的区别

    1 制作过程 静态库 xff1a 生成 o文件后 ar rcs o libxxx a 动态库 xff1a 生成 o文件时 xff0c 静态库是 c选项 xff0c 而动态库是 fpic FPIC xff0c 因为动态库需要生成与位置无关的代
  • 怎么把PWM信号转为模拟量

    有一个测量位置变化的位置传感器 xff0c 用万用表电压档测量传感器的输出信号 xff0c 结果显示的是模拟量信号 xff0c 即位置和信号输出大小呈线性关系 但是 xff0c 用示波器 xff08 Picoscope 4227 xff09
  • STM32环形串口队列程序 大数据串口收发 实时不丢包 串口程序平常产品开发中编写或移植的程序并亲自测试通过,均为工程文件格式,可直接编译使用

    STM32环形串口队列程序 大数据串口收发 实时不丢包 串口程序平常产品开发中编写或移植的程序并亲自测试通过 xff0c 均为工程文件格式 xff0c 可直接编译使用 该程序为大数据量吞吐的串口收发例程 xff0c 中断接收 xff0c 边
  • C语言中的函数返回值、return用法、return 0详解

    1 函数返回值 定义 xff1a 函数的返回值是指函数被调用之后 xff0c 执行函数体中的代码所得到的结果 xff0c 这个结果通过return语句返回 没有返回值的函数为空类型 xff0c 用void表示 一旦函数的返回值类型被定义为
  • TCP协议

    TCP xff08 Transmission Control Protocol xff09 是面向连接的可靠的通讯协议 TCP需要经过三次握手建立连接 xff0c 并在断开时通过四次挥手释放连接 TCP通过应答确认 超时重传 xff08 R