网站推广问题,淘宝上做网站排名,网上商城网站怎么做,英迈思做网站做的怎样TCP报文首部 确认应答机制
TCP 是可靠的#xff0c;指的是它能够确保数据从源端准确无误地传输到目的端。 当客户端和服务器通信时#xff0c;客户端向服务器发送报文#xff0c;那么#xff0c;客户端怎么知道服务器已经收到报文了呢#xff1f; 服务器收到客户端发的报…TCP报文首部 确认应答机制
TCP 是可靠的指的是它能够确保数据从源端准确无误地传输到目的端。 当客户端和服务器通信时客户端向服务器发送报文那么客户端怎么知道服务器已经收到报文了呢 服务器收到客户端发的报文后对收到的报文做出应答也就是说服务器向客户端发送应答报文这样客户端就可以知道服务器收到自己发送的报文了如果客户端没有收到服务器发来的应答说明自己发送的报文丢包了或者服务器发的应答报文丢包了此时客户端重新把该报文发给服务器这样就可以保证 TCP 的可靠性。就像在日常生活中我问朋友 “吃了吗”朋友回复 “吃了”我根据朋友的回答就可以知道朋友听到了我说的话如果朋友没有回复我就再问朋友一次。 那么服务器怎么知道客户端收到了应答呢即需要对应答做应答吗 客户端也可以针对服务器的应答报文发送应答但是这样就陷入死循环了双方不断地对应答作出应答所以 TCP协议规定当 接收方 发送应答给 发送方以确认 接收方 已经成功接收到数据段时发送方 不需要再回送一个确认来确认自己收到了这个应答。即不需要再对应答做应答 不需要对应答做应答意味着虽然应答的发送方无法确认应答的接收方是否接收到了应答即无法确认最新的报文绿色箭头的可靠性但是可以确认的是最新的报文之前的报文即历史上发送的报文对方一定接收到了。 以上的过程对客户端和服务器都是适用的服务器给客户端发报文客户端也需要发送应答报文。除此之外发送应答报文的过程是双方操作系统自动完成的。
在实际情况中发送方一次发多条报文而不是一次只发一条报文接收方需要对收到的所有报文做出应答这时候就需要标识符来区分发送方发送的报文也需要标识符来确定接收方发出去的应答报文是应答哪一条报文于是有了序号和确认序号。 序号和确认序号简易理解 序号可以区分报文应答报文的确认序号是要应答的报文的序号加一。报文的发送方在收到确认序号后就知道确认序号之前的数据都被接收方接收了。比如 A 给 B 发报文B 给 A 的确认序号是 1001那么 A 就知道 B 收到了序号为 1~1000 的数据。 一个报文为什么既需要序号又需要确认序号呢 其实接收方在回应发送方告诉发送方自己接收到了报文的同时也可以告诉发送方新的消息就像朋友回复我 “吃了” 的时候朋友同时也可以问我 “你吃了什么”。 当一方例如B接收到另一方例如A的数据段时B通常需要向A发送一个应答来确认收到了哪些数据。如果此时B也有数据要发送给A则B可以将应答信息包含在自己的数据段头部中一起发送出去。这就避免了专门为应答分配一个独立的TCP段从而节省了带宽。因此在一个TCP会话中双方都可以既是发送者也是接收者。这样的应答叫做捎带应答。如果报文只有序号或者只有确认序号就无法知道捎带应答是应答还是要发新数据。 超时重传
在主机 A 向 主机 B 发报文后需要等待 主机 B 的应答如果主机 A 没有收到应答只能判定 主机 B 没有收到主机 A 发的报文主机 A 重新发送该报文那么主机 A 需要等多久才能认为主机 B 没有收到报文呢
所以需要设置时间超过这个时间主机 A 还没有收到应答就重新发送报文这个时间就是超时重传时间。在TCP协议中超时重传的时间Retransmission Timeout, RTO并不是固定的而是根据网络状况动态调整的。如果超时时间设的太长, 会影响整体的重传效率如果超时时间设的太短, 有可能会频繁发送重复的包。
Linux 中(BSD Unix 和 Windows 也是如此), 超时以 500ms 为一个单位进行控制, 每次判定超时重发的超时时间都是 500ms 的整数倍。
如果重发一次之后, 仍然得不到应答, 等待 2*500ms 后再进行重传。如果仍然得不到应答, 等待 4*500ms 进行重传. 依次类推, 以指数形式递增。累计到一定的重传次数, TCP 认为网络或者对端主机出现异常, 强制关闭连接
TCP报头首部的标志位
为什么需要标志位
主机 A 和 主机 B 通信的过程中同时有很多的主机在和主机 B 通信这些主机有的发送建立连接的报文有的发送正常通信的报文有的发送断开连接的报文这些报文的类型是不一样的所以需要标志位来区分不同类型的报文。
各个标志位的意义
TCP报文中的标志位用于控制TCP连接的状态和数据传输的过程用来指示报文段的特定用途或要求接收方采取的行动以下是TCP报文中的常见六个标志位 URGurgent紧急指针是否有效ACKacknowledgement确认号是否有效当发送应答报文时ACK置1PSHpush提示接收端的应用程序立刻从 TCP 的接收缓冲区把数据读走RSTreset对方要求重新建立连接SYNsynchronize sequence numbers请求建立连接FINfinish发送方已经没有数据要发送了本端要断开连接了 TCP 建立连接三次握手 三次握手是TCP/IP协议中用于在客户端和服务器之间建立连接的过程。通过这个过程通信双方可以同步初始序列号并确认彼此的接收能力确保后续数据传输的准确性和可靠性。以下是三次握手的具体步骤 第一次握手由客户端发送一个带有SYN标志位设置为1的TCP报文给服务器表示请求建立连接。 第二次握手服务器接收到客户端的SYN报文后会回复一个同样带有SYN标志位设置为1的报文以表明同意建立连接同时也将ACK标志位设置为1用来对客户端的SYN进行确认。 第三次握手客户端收到服务器的SYNACK报文后需要再次发送一个报文给服务器作为响应这次报文中的ACK标志位置为1用来确认收到了服务器的SYN。此时客户端与服务器之间的TCP连接成功建立可以开始进行数据传输。 通过这三次握手客户端和服务器都能确定对方的接收和发送能力正常从而确保了连接的可靠性。在三次握手的过程中双方发的都是报头并不会发数据。 如果 第二个 ACK 报文丢包了怎么办RST 报文 经过第一、二次握手时主机 A 认为连接已经建立好了并向主机 B 发送 ACK 报文 主机 B 在收到 主机 A 发送的 ACK 报文后才认为连接建立好了也就是说主机 A 和 主机 B 认为连接建立好的时间点是错开的。 如果主机 A 发送的 ACK 报文丢包了主机 B 认为连接还没有建立好但 主机 A 并不知道这一情况就向 主机 B 发送数据了这时候主机 B 就需要告诉主机 A 连接还没有建立好所以 主机 B 向主机 A 发送 RST 报文 要求主机 A 关闭与主机 B 建立好的连接重新与主机 B 进行三次握手。 通信双方是谁先发起连接的呢 谁先调用 connect 函数谁就先发起连接。客户端发送 SYN 置为1的报头后只有处于 listen 状态即调用了listen函数的服务器才可以受理 SYN 置为 1 的报文并回复 ACK 置为 1 的报文如果服务器没有处于 listen 状态就会丢弃 SYN 置为 1 的报文。connect 函数在三次握手期间一直阻塞等待等待三次握手的结果三次握手成功 connect 返回值为 0失败则返回值为 -1. 连接的维护需要成本吗 服务器同时与多个客户端建立连接就需要管理这些连接根据先描述再组织内核中存在一个数据结构来管理连接对连接的管理本质就是对内核数据结构的管理这些数据结构会消耗操作系统的内存空间和时间所以连接的维护需要时间和空间成本。 为什么是三次握手而不是一次、两次 1、TCP 是全双工的需要保证通信双方既可以发消息也可以接收消息。 主机 A 收到 主机 B 的 ACK 报文说明主机 A 确认 主机 B 既可以接收消息因为主机B收到了 SYN 报文才会发 ACK 报文也可以发消息主机 B 发了 ACK 报文但是主机 B 还无法确认主机 A 是否可以接收消息当主机 A 向 主机 B 发送 ACK 报文时主机 B 确定了主机 A 可以接收消息那么主机 A 和主机 B 都是可以接收消息和发消息的就可以保证全双工。也就是说三次握手是确认全双工的最小次数。一次握手和两次握手无法确认全双工而更多的握手次数会消耗网络资源所以三次握手是最合适的。 2、我们知道连接的维护是需要成本的如果大量的主机向主机 B 发起连接这些连接只是经过一次或者两次握手服务器无法知道哪些连接是成功的哪些连接是失败的但是服务器需要同时维护成功和失败的连接那么服务器就会出现很多闲置连接已经建立但长时间未进行数据传输或操作的连接从而消耗服务器的资源。 3、其实三次握手也可以看作四次握手只是中间的两次握手即主机 B 向主机 A 的 ACK 和 SYN 报文被合并为捎带应答报文了。 TCP 断开连接四次挥手 第一次挥手主动关闭方可以是客户端或服务器视具体情况而定发送一个FINFinish标志位设置为1的报文段表示希望断开连接。此时该方进入FIN_WAIT_1状态。 第二次挥手被动关闭方接收到FIN报文后会回复一个ACKAcknowledgment报文段确认收到了对方的关闭请求并且将序号调整为接收到的FIN报文序列号加1。之后被动关闭方进入CLOSE_WAIT状态而主动关闭方收到这个ACK后进入FIN_WAIT_2状态。 第三次挥手当被动关闭方准备好关闭连接时即它也没有数据要发送了它会发送自己的FIN报文段给主动关闭方表示同意关闭连接。这时被动关闭方进入LAST_ACK状态。 第四次挥手主动关闭方收到被动关闭方的FIN报文后需要再次发送一个ACK报文作为回应并将序号设置为接收到的FIN报文序列号加1。然后主动关闭方进入TIME_WAIT状态等待一段时间通常是MSL最大报文生存时间的两倍以确保网络中的重复报文已消失后最终关闭连接。被动关闭方在收到这个ACK后立即关闭连接。 为什么中间两次挥手不合并 断开连接应该看作 主机 A 与 主机 B 断开连接主机 B 也和主机 A 断开连接。主机 A 与主机 B 断开连接时意味着 主机 A 已经没有数据要发给主机 B 了主机 A 要关闭发送缓冲区了但是 主机 B 可能还要主机 A 发消息或者有的报文还在网络中阻塞所以需要等消息都被接收后主机 B 才发报文与主机 A 断开连接。所以在中间两次挥手之间需要等待一段时间等待消息的到达。