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协议 的相关文章

  • 您可以通过 TcpClient 发送大于 SendBufferSize 的文件吗?

    我正在试验 NET 中的 Tcp 连接 我想发送一些大于 TcpClient 对象的 SendBufferSize 比例的数据 是否可以通过简单地写入网络流来发送数据 或者我是否需要将其切成小块并发送这些数据 然后在另一端再次创建它 Fro
  • 文件上传流从哪里获取内容?

    我有一个关于文件上传的问题 这与它的工作原理更相关 而不是代码问题 我在互联网上查看 但找不到正确的答案 我有一个在 tomcat 上运行的 Web 应用程序 它处理文件上传 通过 servlet 假设我现在想要上传大文件 gt 1 GB
  • vertx 内的多线程

    我是 vert x 的新手 我正在尝试 vert x NetServer 功能 http vertx io core manual java html writing tcp servers and clients http vertx i
  • TCP recvfrom() 不存储“from”

    我正在使用 TCP 制作一个服务器程序 我想获取我刚刚收到的消息发送者的 IP 地址 这是我的代码 case FD READ Incoming data get ready to receive char buffer DEFAULT BU
  • 用 C 处理 TCP 的部分返回

    我一直在读Beej 的网络编程指南 http beej us guide bgnet 获取 TCP 连接的句柄 在其中一个示例中 简单 TCP 流客户端的客户端代码如下所示 if numbytes recv sockfd buf MAXDA
  • wireshark 和 tcpdump -r:奇怪的 tcp 窗口大小

    我正在使用 tcpdump 捕获 http 流量 并且对 TCP 慢启动以及窗口大小如何增加感兴趣 sudo tcpdump i eth1 w wget tcpdump tcp and port 80 当我使用 Wireshark 查看转储
  • Boost ASIO:服务器如何知道客户端是否仍然连接?

    我在用boost asio对于服务器 客户端应用程序 服务器一次只接受一个连接 我想知道服务器验证客户端是否仍然连接的最佳方法是什么 这样做的目的是我希望能够知道客户端是否崩溃 以便我可以重新开始侦听新的连接尝试 在我的应用程序中 我使用以
  • Linux Socket write() 的错误文件描述符 错误的文件描述符 C

    我对 write 2 函数有一个有趣的问题 PrepareResponseForSetCoordinates 函数会导致写入时出现错误的文件描述符错误 这是错误行 perror 写入套接字时出错 总产量 写入套接字时出错 文件描述符错误 我
  • 是什么导致 MSSQL 中出现“非阻塞套接字上的操作将阻塞”错误?

    错误 异常查询为 CREATE NONCLUSTERED INDEX I1 ON AllAccounts BAK Master received Day ASC 出现异常 发生一个或多个错误 错误 异常内部异常无法从传输连接读取数据 非阻塞
  • TCP Socket无连接超时

    我打开一个 TCP 套接字并将其连接到网络上其他位置的另一个套接字 然后我就可以成功发送和接收数据 我有一个计时器 每秒向套接字发送一些内容 然后 我通过强行断开连接 在本例中拔出以太网电缆 来粗暴地中断连接 我的套接字仍然报告它每秒都在成
  • 我的代码中某处存在无限循环

    我有这个 Java 游戏服务器 最多可处理 3 000 个 tcp 连接 每个玩家或每个 tcp 连接都有自己的线程 每个线程的运行情况如下 public void run try String packet char charCur ne
  • 如何模拟客户端和服务器之间的套接字断开连接(在 Windows 上)?

    我已经实现了一种 心跳解决方案 我想看看在实际情况下网络 故障 时会发生什么 特别是当套接字上没有流量时发生这种情况 问题 我只有一台电脑 我在windows java上 我想简单地拔掉网线 停用网卡不会影响这两个进程 因为它们在同一个盒子
  • 如何在NodeJS中测试socket.setKeepAlive

    我尝试在NodeJS中测试setKeepAlive 的功能 我在同一本地网络中的不同计算机上运行 Server js 和 client js 然后 我关闭了客户端计算机上的 WiFi 连接 断开互联网连接 15分钟后 仍然没有消息抛出 这是
  • net.TCPConn 允许在 FIN 数据包后写入

    我正在尝试为一些服务器端代码编写单元测试 但我在确定关闭测试用例时遇到了困难 环回 TCP 连接似乎无法正确处理干净关闭 我在一个示例应用程序中重现了这一点 该应用程序按顺序执行以下操作 创建客户端和服务器连接 通过从客户端向服务器成功发送
  • Web 服务器可以处理多少个套接字连接?

    假设我要获得共享 虚拟或专用托管 我在某处读到服务器 计算机一次只能处理 64 000 个 TCP 连接 这是真的吗 无论带宽如何 任何类型的托管可以处理多少个 我假设 HTTP 通过 TCP 工作 这是否意味着只有 64 000 个用户可
  • 如何在java应用程序中检测FIN - tcp标志?

    我在两台计算机之间有持久的 TCP 连接 第二台计算机不受我的控制 第二台计算机可以随时发送FIN标志 并且首先必须关闭当前连接 将FIN标志发送回第二台计算机 我如何知道第二台计算机正在发送 FIN 标志 以及何时必须调用 Java 应用
  • 如何在Linux中打开端口[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我已经安装了 Web 应用程序 该应用程序在 RHEL centOS 上的端口 8080 上运行 我只能通过命令行访问该机器 我尝试从我的
  • 视频流上的 TCP 与 UDP

    我刚从网络编程考试回来 他们问我们的问题之一是 如果您要传输视频 您会使用 TCP 还是 UDP 请解释一下存储视频和实时视频流 对于这个问题 他们只是希望得到一个简短的答案 TCP 用于存储视频 UDP 用于实时视频 但我在回家的路上想到
  • 简单的跨平台 TCP IP API?

    我不打算使用像 QT 或 wxWidgets 的 API 这样的大东西 我只想要可以在 Android iOS Windows Mac Linux 上运行的简单套接字 我正在制作一个事件驱动的纸牌游戏 所以 TCP 是最好的 本质上 我只想
  • 我应该害怕使用 UDP 进行客户端/服务器广播通话吗?

    我在过去的两天里阅读了每一篇StackOverflow问题和答案 以及googling当然 关于印地TCP and UDP协议 以便决定在我的用户应用程序和 Windows 服务之间的通信方法中应该使用哪一种 从我目前所看到的来看 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