TCP连接的“三次握手”与“四次挥手”

2024-05-29 23:32

本文主要是介绍TCP连接的“三次握手”与“四次挥手”,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

TCP报文格式

TCP报文格式

  1. 序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
  2. 确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
  3. 标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
  • URG:紧急指针(urgent pointer)有效。
  • ACK:确认序号有效。
  • PSH:接收方应该尽快将这个报文交给应用层。
  • RST:重置连接。
  • SYN:发起一个新连接。
  • FIN:释放一个连接。

注意:

  • 不要将确认序号Ack与标志位中的ACK搞混了。
  • 确认方Ack=发起方Req+1,两端配对。

建立连接——三次握手

所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。由客户端执行connect()触发
  三次握手,建立连接

  1. 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
  2. 第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
  3. 第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

断开连接——四次挥手

所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。由客户端或服务端任一方执行close来触发
  四次挥手,断开连接
每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。

  1. 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
  2. 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
  3. 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
  4. 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

同时发起主动关闭的情况:

同时发起主动关闭,同时挥手

问题

  1. 三次握手是什么或者流程?四次握手呢?
  2. 为什么连接的时候是三次握手,关闭的时候却是四次握手?
    因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
  3. 为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
    虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。

参考

  1. http://blog.chinaunix.net/uid-7411781-id-3812206.html
  2. http://blog.csdn.net/whuslei/article/details/6667471
  3. 推荐:TCP的三次握手与四次挥手(详解+动图)

目录

文章目录

  • **TCP报文格式**
  • **建立连接——三次握手**
  • **断开连接——四次挥手**
  • **问题**
  • **参考**
  • **目录**

这篇关于TCP连接的“三次握手”与“四次挥手”的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1014938

相关文章

【Altium】查找PCB上未连接的网络

【更多软件使用问题请点击亿道电子官方网站】 1、文档目标: PCB设计后期检查中找出没有连接的网络 应用场景:PCB设计后期,需要检查是否所有网络都已连接布线。虽然未连接的网络会有飞线显示,但是由于布线后期整板布线密度较高,虚连,断连的网络用肉眼难以轻易发现。用DRC检查也可以找出未连接的网络,如果PCB中DRC问题较多,查找起来就不是很方便。使用PCB Filter面板来达成目的相比DRC

Java面试题:通过实例说明内连接、左外连接和右外连接的区别

在 SQL 中,连接(JOIN)用于在多个表之间组合行。最常用的连接类型是内连接(INNER JOIN)、左外连接(LEFT OUTER JOIN)和右外连接(RIGHT OUTER JOIN)。它们的主要区别在于它们如何处理表之间的匹配和不匹配行。下面是每种连接的详细说明和示例。 表示例 假设有两个表:Customers 和 Orders。 Customers CustomerIDCus

神经网络第一篇:激活函数是连接感知机和神经网络的桥梁

前面发布的文章介绍了感知机,了解了感知机可以通过叠加层表示复杂的函数。遗憾的是,设定合适的、能符合预期的输入与输出的权重,是由人工进行的。从本章开始,将进入神经网络的学习,首先介绍激活函数,因为它是连接感知机和神经网络的桥梁。如果读者认知阅读了本专题知识,相信你必有收获。 感知机数学表达式的简化 前面我们介绍了用感知机接收两个输入信号的数学表示如下:

PHP ODBC:连接数据库的桥梁

PHP ODBC:连接数据库的桥梁 PHP ODBC(Open Database Connectivity)是一个允许PHP应用程序连接到各种数据库管理系统的扩展。它为PHP提供了一个标准的数据库访问接口,使得开发者可以编写不依赖于特定数据库系统的代码。本文将详细介绍PHP ODBC的概念、工作原理、使用方法以及在实际开发中的应用。 什么是PHP ODBC? PHP ODBC扩展使得PHP能

使用MySQL WorkBbench 连接远程服务器上的mysql教程(包含踩过的坑)

最近在学习MySQL,想要装一个可视化程序,但是希望把脏活累活留给服务器,于是自己电脑上安装了一个MySQL Workbench作为Client。下面记录一下配置的过程。 服务器端MySQL配置 安装MySQL这里就不赘述啦,可以参考 https://segmentfault.com/a/1190000023081074 然后是设置MySQL远程访问 打开配置文件修改连接地址 设置用户远程登

client-go入门之1:创建连接Kubernetes集群的客户端

文章目录 简介使用 简介 我们可以使用Dashboard或kubectl来访问k8s的API,也可以使用编程语言,如Go,Java,Python作为客户端来访问k8s。client-go是一个使用go语言编写的库,用来连接k8s集群并对集群资源进行操作。 使用 以下代码使用go连上k8s集群,并查询集群的节点信息: package mainimport ("fmt"meta

TCP 可靠传输的工作原理

转载地址:https://my.oschina.net/xinxingegeya/blog/485233 感谢原作者 TCP 可靠传输的工作原理 ARQ(Automatic Repeat-reQuest)(自动重传请求) 停止等待ARQ协议 连续ARQ协议   停止等待ARQ协议 全双工通信的双发既是发送方也是接收方。下面为了讨论问题的方便,我们仅考虑A发送数据而B接受数据

VS Code SSH 远程连接服务器及坑点解决

背景 Linux服务器重装了一下,IP没有变化,结果VS Code再重连的时候就各种问题,导致把整个流程全部走了一遍,留个经验帖以备查看 SSH 首先确保Windows安装了ssh,通过cmd下ssh命令查看是否安装了。 没安装,跳转安装Windows下的ssh 对应的,也需要Linux安装ssh,本文是Ubuntu系统,使用以下命令安装: sudo apt updatesudo

ESP32使用MQTT_TCP连接阿里云

ESP32-IDF中MQTT函数的介绍 esp_mqtt_client_handle_t esp_mqtt_client_init(const esp_mqtt_client_config_t *config) 函数功能:mqtt 客户端初始化 函数形参: mqtt 客户端的配置 函数返回值:正确则返回根据配置创建的 mqtt 客户端句柄;异常则返回 NULL。 其中函数形参 esp_mqtt