详解TCP连接的建立

2023-05-16

  1. TCP首部格式

    TCP报文段首部的前20个字节是固定的,后面有4N字节是根据需要而增加的选项,因此TCP报文段的最小长度为20字节。
    首部固定部分的各字段的意义如下:
    1.源端口和目的端口:加上IP首部的源IP地址和目的IP地址,确定唯一的一个TCP连接。另外通过目的端口来决定TCP将数据报交付于哪个应用程序,从而实现TCP的分用功能。
    2.序列号:占4个字节,序列号的范围为[0到2的32次幂],由于TCP是面向字节流的,在一个TCP连接中传送的字节流中的每一个字节都按顺序编号,首部中的序列号字段则是指本报文段所发送的数据的第一个字节的序列号,另外序列号是循环使用的,当序列号增加到最大值时,下一个序列号就又回到了0。
    3.确认号:当ACK标志位为1时有效,表示期望收到的下一个报文段的第一个数据字节的序列号。确认号为N,则表示序列号N-1为止的所有数据字节都已经被正确地收到了。
    4.首部长度:TCP报文段的首部长度,它指出TCP报文段的数据部分的起始位置与TCP报文段的起始位置的距离。头部长度占4个字节,但它的单位是4字节,因此首部长度的最大值为15×4=60字节,这就意味着选项的长度不超过40字节。
    5.保留位:必须为0。
    6.下面的6个控制位说明报文段的性质:
    (1)URG(URGent):与首部中的紧急指针字段配合使用。当URG为1时,表明紧急指针字段有效,发送应用进程告诉发送方的TCP有紧急数据要传送,于是发送方TCP就把紧急数据插入到本报文段数据的最前面,而其后面仍是普通数据。
    (2)ACK(ACKnowledgement):仅当ACK=1时确认号字段才有效,当ACK=0时,确认号无效。TCP规定:在连接建立后所有的传送报文段置1。
    (3)PSH(PUSH):如果发送的报文段中PSH为1,则接收方接收到该报文段后,直接将其交付给应用程序,而不再等待缓存都填满后再向上交互。
    (4)RST(RESET):复位标志,RST为1时,表明TCP连接中出现严重差错,必须释放连接,然后重新建立运输连接。
    (5)SYN(SYNchronization):同步序号,用来发起一个连接。当SYN=1而ACK=0时,表明这是一个连接请求报文段,若对方同意建立连接,则应在响应的报文段中使SYN=1和ACK=1。
    (6)FIN(FINish):用来释放一个连接。当FIN=1时,表明此报文段的发送方的数据已发送完毕,并要求释放连接。
    7.窗口:接收方让发送方下次发送报文段时设置的发送窗口大小。
    8.校验和:校验的字段范围包括首部和数据这两部分。
    9.紧急指针:当URG=1时才有效,它指出本报文段中的紧急数据的字节数。PS:即使窗口为0时,也可发送紧急数据。
    10.选项与填充:选项应为4字节的整数倍,否则用0填充。最常见的可选字段是最长报文大小MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段中指明这个选项。它指明本端所能接收的最大长度的报文段。该选项如果不设置,默认为536(20+20+536=576的IP数据报),其中IP首部和TCP首部各20个字节,而internet上标准的MTU(Maximum Transmission Unit最大传输单元)最小为576B。

  2. TCP连接的建立

    服务端的TCP进程先创建传输控制块TCB,准备接收客户端进程的连接请求,然后服务端进程处于LISTEN,等待客户端的连接请求,如有,则作出响应。
    1.客户端的TCP进程也首先创建传输控制模块TCB(Transmission control module),然后向服务端发出连接请求报文段,该报文段首部中SYN=1,ACK=0,同时选择一个初始序号seq=i。TCP规定:SYN=1的报文段不能携带数据,但要消耗掉一个序号。这时,TCP客户进程进入SYN-SENT(同步已发送)状态,这时TCP的第一次握手。
    2.服务端收到客户端发来的请求报文后,如果同意建立连接,则向客户端发送确认。确认报文中的SYN=1,确认号ack=i+1,同时为自己选择一个初始序号seq=j。同样该报文段也是SYN=1的报文段,不能携带数据,但同样要消耗掉一个序号。这时,TCP服务端进入SYN-RCVD(received),这是TCP连接的第二次握手。
    3.TCP客户端进程收到服务端进程的确认后,还要向服务端给出确认。确认报文段的ACK=1,确认号ack=j+1,而自己的序号为seq=i+1。TCP的标准规定,ACK报文段可以携带数据,但如果不携带数据则不消耗序号。因此,如果不携带数据,则下一个报文段的序号仍为seq=i+1。这时,TCP连接已经建立,客户端进入ESTABLISHED(已建立连接)状态。这是TCP连接的第三次握手,可以看出第三次握手客户端已经可以发送携带数据的报文段了。
    当服务端收到确认后,也进入已建立连接状态。

  3. 双方同时主动连接的TCP连接建立过程
    正常情况下,传输连接都是由一方主动发起的,但也有可能双方同时主动发起连接,此时就会发生连接碰撞,最终只有一个连接能够建立起来。因为所有连接都是由它们的端点进行标识的。如果第一个连接请求建立起一个由套接字(x,y)标识的连接,而第二个连接也建立了这样一个连接,那么在TCP实体内部只有一个套接字表项。
    当出现同时发出连接请求时,则两端几乎在同时发送一个SYN字段置1的数据段,并进入SYN_SENT状态。当每一端收到SYN数据段时,状态变为SYN_RCVD,同时它们都再发送SYN字段置1,ACK字段置1的数据段,对收到的SYN数据段进行确认。当双方都收到对方的SYN+ACK数据段后,便都进入ESTABLISHED状态。但最终建立的是一个TCP连接。

    PS:一个双方同时打开的传输连接需要交换4段数据段,比正常的传输连接建立所进行的3次握手多交换1个数据段。此时没有任何一端称为客户或服务器,因为每一端既是客户又是服务器。

  4. 为什么一定要进行三次握手呢?
    1.前2次的握手很显然是必须的,主要是最后一次,这主要是为了防止已失效的请求报文段突然又传送到了服务端而产生连接的误判。
    2.考虑如下的情况:客户端发送了一个连接请求报文段到服务端,但是在某些网络节点上长时间滞留了,而后客户端又超时重发了一个连接请求报文段到该服务端,而后正常建立连接,数据传输完毕,并释放了连接。如果这时候第一次发送的请求延迟了一段时间后,又到了服务端,很显然,这本是一个早已失效的报文段,但是服务端收到后会误以为客户端又发出了一次连接请求,于是向客户端发出确认报文段,并同意建立连接。假设不采用3次握手,这时只要发送了确认,新的连接就建立了,但由于客户端并没有发出建立连接的请求,因此不会理会服务端的确认,也不会向服务端发送数据,而服务端却认为新的连接已经建立了,并在一直等待客户端发送数据,这样服务端就会一直等待下去,直到超出保活计数器的设定值,而将客户端判定为出了问题,才会关闭这个连接,这样就浪费了很多服务器的资源。而如果采用三次握手,客户端就不会向服务端发出确认,服务端由于收不到确认,就知道客户端没有要求建立连接,从而不建立连接。

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

详解TCP连接的建立 的相关文章

  • Spring Integration TCP - 在发送数据之前启动消息握手

    我正在使用 MessagingGateway 将数据发送到服务器 我为出站网关配置了 AbstractClientConnectionFactory 和 ServiceActivator 为了将数据发送到我的服务器 我需要在启动连接时发送握
  • 定义新的套接字选项以在 TCP 内核代码中使用

    我正在尝试向 TCP 内核代码添加一些功能 在tcp input c 我希望我实现的代码仅在某些情况下运行 我想添加一个控制标志 可以从用户空间应用程序设置它 我 认为我 需要添加一个新的套接字选项 以便我可以完成以下操作setsockop
  • 如何通过 GPRS 向 GPS 追踪器(TK103、GT02、GT06、TK102 等)发送命令

    这已经被问过这里https stackoverflow com questions 25460743 gps tracker tk103 how to send message through server https stackoverf
  • TCPServer 具有同时全双工通信

    我正在尝试编写一个 C 服务器 客户端 它将同时通过 TCP 相互发送字节数组 我正在努力思考如何实现这一目标 我见过的所有示例都等待消息 然后发送响应 我需要同时进行沟通 我是否需要为服务器和客户端上的传入和传出创建 2 个单独的 TCP
  • 用 C 处理 TCP 的部分返回

    我一直在读Beej 的网络编程指南 http beej us guide bgnet 获取 TCP 连接的句柄 在其中一个示例中 简单 TCP 流客户端的客户端代码如下所示 if numbytes recv sockfd buf MAXDA
  • Python。从 6 字节字符串中打印 mac 地址

    我有 6 字节字符串的 mac 地址 您将如何以 人类 可读的格式打印它 Thanks import struct x x x x x x struct unpack BBBBBB your variable with mac
  • 如何识别用户空间和内核空间之间的特定套接字?

    我在用户空间中有一个库 可以拦截套接字层调用 例如socket connect accept 等等 我只处理 TCP 套接字 在内核空间中 我有一个网络内核模块 它处理所有 TCP 连接 我需要能够在驱动程序中识别哪些套接字被用户空间库拦截
  • wireshark 和 tcpdump -r:奇怪的 tcp 窗口大小

    我正在使用 tcpdump 捕获 http 流量 并且对 TCP 慢启动以及窗口大小如何增加感兴趣 sudo tcpdump i eth1 w wget tcpdump tcp and port 80 当我使用 Wireshark 查看转储
  • Socat未关闭tcp连接

    I use socat 1 7 3 1 r0并在alpine 3 3linux服务器 socat d d d PTY link dev ttyFOOBAR echo 0 raw unlink close 0 TCP LISTEN 7000
  • tcp_max_syn_backlog 和 somaxconn 有什么区别?

    我一直在阅读一些关于 Linux 上的 TCP 实现的文章 我很困惑 它们之间有什么区别net ipv4 tcp max syn backlog and net core somaxconn和backlog作为参数传递给listen 系统调
  • Socket ReceiveAsync 合并数据包

    我打算通过套接字接收数据包 但由于它们是从发送方以高频率发送的 因此其中许多数据包被打包成一个byte array SocketAsyncEventArgs Buffer然后保存多个数据包 即使它们是单独发送的 使用验证wireshark
  • syn队列和accept队列的混淆

    在阅读TCP源码时 我发现一个困惑的事情 我知道 TCP 在 3 次握手中有两个队列 第一个队列存储服务器收到的连接SYN并发回ACK SYN 我们称之为同步队列 第二个队列存储3WHS成功并建立连接的连接 我们称之为接受队列 但在阅读代码
  • C# - 从客户端检查 TCP/IP 套接字状态

    我想为我的 TCP IP 客户端类提供 CheckConnection 函数 以便我可以检查是否发生了错误 我自己的客户端断开连接 服务器断开连接 服务器卡住等 我有类似的东西 bool isConnectionActive false i
  • 如何模拟 TCP/IP 错误?

    在多层应用程序上 我需要模拟各种 TCP IP 错误来测试一些重新连接代码 有谁知道我可以使用什么工具 基于 Windows 来实现此目的 谢谢 Scapy http secdev org projects scapy 允许您控制数据包的各
  • 在 Golang Server 中接受持久的 tcp 连接

    我正在尝试使用 Go 并且想创建一个 TCP 服务器 我可以通过 telnet 访问该服务器 发送命令并接收响应 const CONN HOST localhost CONN PORT 3333 CONN TYPE tcp func mai
  • 如何在Linux中打开端口[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我已经安装了 Web 应用程序 该应用程序在 RHEL centOS 上的端口 8080 上运行 我只能通过命令行访问该机器 我尝试从我的
  • 无法分配请求的地址 - 可能的原因?

    我有一个由主服务器和分布式从服务器组成的程序 从属服务器向服务器发送状态更新 如果服务器在固定时间内没有收到特定从属服务器的消息 则会将该从属服务器标记为关闭 这种情况一直在发生 通过检查日志 我发现从站只能向服务器发送一个状态更新 然后永
  • 为什么 UDP 服务器中只有一个套接字?

    我正在准备考试 发现了这个问题 典型的 UDP 服务器可以使用单个套接字来实现 解释一下为什么 对于 TCP 驱动的服务器 我发现创建了两个套接字 一个用于所有客户端访问服务器 另一个用于每个客户端的特定 套接字 用于服务器和客户端之间的进
  • 如何查找连接到 AF_INET 套接字的客户端的 UID?

    有什么方法或类似的东西ucred for AF UNIX如果是AF INET插座 TCP在我的例子中 找出连接到我的套接字的客户端的UID 还有 proc net tcp但它显示了UID of the creator插座的而不是连接的cli
  • 如何强制关闭 TcpListener

    我有一个通过 tcpListener 进行通信的服务 问题是当用户重新启动服务时 抛出 地址已在使用 异常 并且服务在几分钟左右无法启动 有没有办法告诉系统终止旧连接 以便我可以打开一个新连接 我不能只使用随机端口 因为服务无法通知客户端端

随机推荐

  • JAVA实现HTTPS协议POST请求JSON报文

    HTTPS和HTTP的区别 超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息 HTTP协议以明文方式发送内容 xff0c 不提供任何方式的数据加密 xff0c 如果攻击者截取了Web浏览器和网站服务器之间的传输报文 x
  • Jmeter之JAVA Request的应用

    当我们使用Jmeter进行接口测试的时候 xff0c 我们一定会遇到一个问题 xff0c 那就是如果这些接口不是http协议的 xff0c 是经过封装以后的接口 xff0c 用Jmeter该怎么解决呢 xff1f 当你想到这个问题 xff0
  • FreeRTOS例程3-串口中断接收不定长的数据与二值信号量的使用

    FreeRTOS例程3 串口中断接收不定长的数据与二值信号量的使用 知乎 zhihu com
  • 使用airtest实现UI自动化之环境搭建

    1 xff0c 安装python python版本为3 7 1 2 xff0c 安装airtest xff0c pocoui模块 在安装时碰到的问题 xff1a 1 xff09 使用pip命令报错 xff0c 报SSL证书无法识别错误 解决
  • HTTP Digest Authentication在实际应用中的问题

    作者 xff1a 老王 Basic认证实际上是明文传递密码 xff0c 所以 RFC2617里定义了Digest认证以取代它 xff0c 其计算方法如下 xff1a 其中HA1计算方法为 xff1a 如果qop选项的值为auth xff0c
  • 1天精通Apipost--全网最全gRPC调试和智能Mock讲解!

    gRPC 接口调试 grpc 作为一个老程序员 xff0c 最近公司技术架构用到了gPRC xff0c 但国内很少有支持这个的工具 xff0c 大部分都只是支持http 由于我同时也是Apipost骨灰级用户 xff0c 于是就在他们官网的
  • CAN总线波特率的设定——以STM32为例

    波特率的设定 首先是几个名词的含义 xff0c CAN里面1个位的构成如下 注意采样点的位置在PBS1和PBS2的中间 根据这个位时序就可以计算波特率了 最小时间单位 xff08 Tq xff0c Time Quantum xff09 同步
  • 2021电赛备赛心路历程(含代码例程)

    作为一个电子学院学生 xff0c 大二暑假才开始自学单片机知识 xff08 还是因为报名了电赛而不得不去学 xff09 xff0c 深感愧疚 从今年7月至8 4的将近四周时间内哩哩啦啦学了一些基础模块 xff08 其中光是练习点灯和其他基础
  • 20201114-三轴云台storm32 BGC HAKRC调试+

    storm32 BGC HAKRC 2轴云台支持俯仰 xff08 抬头低头 xff09 以及横滚 xff1b 三轴多了一个航向 支持锁头模式 xff0c 拍摄更方便 可以控制俯仰通过接收机或者其他单独PWM通道 可以设置跟随模式或者锁定模式
  • KEIL5中头文件路劲包含问题

    方式1 xff1a 1 Keil中添加头文件相对路劲的方法 在c c 43 43 配置中添加路劲 xff0c 最终是将添加的绝对路径转化为相对路径 xff1b 注意 xff1a 相对路径的当前位置指 uvproj文件所在位置 在C C 43
  • php curl函数应用方法之模拟浏览器

    curl 是使用URL语法的传送文件工具 xff0c 支持FTP FTPS HTTP HTPPS SCP SFTP TFTP TELNET DICT FILE和LDAP curl 支持SSL证书 HTTP POST HTTP PUT FTP
  • WireShark基本抓包数据分析

    WireShark抓包数据分析 xff1a 1 TCP报文格式 源端口 目的端口 xff1a 16位长 标识出远端和本地的端口号 顺序号 xff1a 32位长 表明了发送的数据报的顺序 确认号 xff1a 32位长 希望收到的下一个数据报的
  • VScode下运行调试C++文件

    1 下载vscode 这个可以直接去官网下载 2 下载mingw64 下载mingw64就是下载C 43 43 的编译器g 43 43 和调试器gdb 这个也可以去官网下载 xff0c 下载安装完成后去配置环境变量 我将mingw64安装在
  • c++模板的优点和缺点

    作为C 43 43 语言的新组成部分 xff0c 模板引入了基于通用编程的概念 通用编程是一种无须考虑特定对象的描述和发展算法的方法 xff0c 因此它与具体数据结构无关 但在决定使用C 43 43 模板之前 xff0c 让我们分析一下使用
  • 基于导航网格的A星寻路(Navigation mesh)

    最近花了几个月的时间实现了导航网格寻路和导航网格自动生成 导航网格数据结构定义 由于数据之间有着层级关系 xff0c 所以采用XML进行定义 navmesh基本元素 xff1a 顶点 Verts 43 可走边 Edges 43 凸多边形 P
  • cmake 引入 动态库、静态库

    动态库 xff1a link directories PROJECT SOURCE DIR lib 添加动态连接库的路径 target link libraries project name lMNN 添加libMNN so 静态库 xff
  • 利用JSP内置对象Request和Application实现用户名密码登录注册进入首页显示

    学习目标 xff1a 实验名称 xff1a JSP内置对象目的 xff1a 掌握JSP页面的全部语法 能够编写基本的JSP网页 学习内容 xff1a 1 实验 地点 周三2单元 xff0c 10617综合一实验室 自带电脑 目的 掌握各种内
  • 【如何写CMake】一个解决方案,多个工程

    文章目录 代码参考 一个解决方案 xff0c 多个工程 xff0c 即多个exe dll lib等 代码 多加几个ADD EXECUTABLE即可 1 cmake verson xff0c 指定cmake版本 cmake minimum r
  • 指针、寄存器、位操作

    定义寄存器的绝对地址 xff0c 并转换为指针进行位操作 1 位操作示例一 define PERIPH BASE unsigned int 0x40000000 define APB2PERIPH BASE PERIPH BASE 43 0
  • 详解TCP连接的建立

    TCP首部格式 TCP报文段首部的前20个字节是固定的 xff0c 后面有4N字节是根据需要而增加的选项 xff0c 因此TCP报文段的最小长度为20字节 首部固定部分的各字段的意义如下 xff1a 1 源端口和目的端口 xff1a 加上I