网络基础知识(4)——建立与关闭连接

news2025/1/21 18:42:55

建立 TCP 连接:三次握手  

        前面我们提到过,TCP 协议是一个面向连接的协议,双方在进行网络通信之间,都必须先在双方之间建立一条连接,俗称“握手”,可能在学习网络编程之前,大家或多或少都听过“三次握手”、“四次挥手” 这些词语,那么“三次握手”、“四次挥手”究竟是什么意思,本文将详细讨论一个 TCP 连接是如何建立的,需要经过哪些过程。

        “三次握手”其实是指建立 TCP 连接的一个过程,通信双方建立一个 TCP 连接需要经过“三次握手” 这样一个过程。         

        首先建立连接的过程是由客户端发起,而服务器会时刻监听、等待着客户端的连接,其示意图如下所示:

        TCP 连接一般来说会经历以下过程:

  • 第一次握手

        客户端将 TCP 报文标志位 SYN 置为 1,随机产生一个序号值 seq=J,保存在 TCP 首部的序列号(Sequence Number)字段里,指明客户端打算连接的服务器的端口,并将该数据包发送给服务器端,发送完毕后,客户端进入 SYN_SENT 状态,等待服务器端确认。

  • 第二次握手

        服务器端收到数据包后由标志位 SYN=1 知道客户端请求建立连接,服务器端将 TCP 报文标志位 SYN 和 ACK 都置为 1,ack=J+1,随机产生一个序号值 seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入 SYN_RCVD 状态。

  • 第三次握手

        客户端收到确认后,检查 ack 是否为 J+1,ACK 是否为 1,如果正确则将标志位 ACK 置为 1,ack=K+1, 并将该数据包发送给服务器端,服务器端检查 ack 是否为 K+1,ACK 是否为 1,如果正确则连接建立成功, 客户端和服务器端进入 ESTABLISHED 状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。

        注意:上面写的 ack 和 ACK,不是同一个概念:

        小写的 ack 代表的是头部的确认号 Acknowledge number,ack。

        大写的 ACK,则是 TCP 首部的标志位,用于标志的 TCP 包是否对上一个包进行了确认操作,如果确认了,则把 ACK 标志位设置成 1。

        在完成握手后,客户端与服务器就成功建立了连接,同时双方都得到了彼此的窗口大小,序列号等信息,在传输 TCP 报文段的时候,每个 TCP 报文段首部的 SYN 标志都会被置 0,因为它只用于发起连接,同步序号。

        为什么需要三次握手?

        其实 TCP 三次握手过程跟现实生活中的人与人之间的电话交流很类似,譬如 A 打电话给 B:

        A:“喂,你能听到我的声音吗?” 

        B:“我听得到呀,你能听到我的声音吗?”

        A:“我能听到你,………”


        经过三次的互相确认,大家就会认为对方对听的到自己说话,才开始接下来的沟通交流,否则,如果不进行确认,那么你在说话的时候,对方不一定能听到你的声音。所以,TCP 的三次握手是为了保证传输的安全、可靠。

关闭 TCP 连接:四次挥手

        除了“三次握手”,还有“四次挥手”,“四次挥手”(有一些书也会称为四次握手)其实是指关闭 TCP 连接的一个过程,当通信双方需要关闭 TCP 连接时需要经过“四次挥手”这样一个过程。

        四次挥手即终止 TCP 连接,就是指断开一个 TCP 连接时,需要客户端和服务端总共发送 4 个包以确认连接的断开。在 socket 编程中,这一过程由客户端或服务端任一方执行 close 触发。

        由于 TCP 连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个 FIN 来终止这一方向的连接,收到一个 FIN 只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个 TCP 连接上仍然能够发送数据,直到这一方向也发送了 FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。

        四次挥手过程的示意图如下:

         挥手请求可以是 Client 端,也可以是 Server 端发起的,我们假设是 Client 端发起:

  •  第一次挥手

        Client 端发起挥手请求,向 Server 端发出一个 FIN 报文段主动进行关闭连接,此时报文段的 FIN 标志位被设置为 1。此时,Client 端进入 FIN_WAIT_1 状态,这表示 Client 端没有数据要发送给 Server 端了。

  • 第二次挥手

        Server 端收到了 Client 端发送的 FIN 报文段,向 Client 端返回一个 ACK 报文段,此时报文段的 ACK 标志位被设置为 1。ack 设为 seq 加 1,Client 端进入 FIN_WAIT_2 状态,Server 端告诉 Client 端,我确认并同意你的关闭请求。

  • 第三次挥手

        Server 端向 Client 端发送一个 FIN 报文段请求关闭连接,此时报文段的 FIN 标志位被设置为 1,同时 Client 端进入 LAST_ACK 状态。

  • 第四次挥手

        Client 端收到 Server 端发送的 FIN 报文段后,向 Server 端发送 ACK 报文段(此时报文段的 ACK 标志位被设置为 1),然后 Client 端进入 TIME_WAIT 状态。Server 端收到 Client 端的 ACK 报文段以后,就关闭连接。此时,Client 端等待 2MSL 的时间后依然没有收到回复,则证明 Server 端已正常关闭,那好,Client 端也可以关闭连接了。

        这就是关闭 TCP 连接的四次挥手过程。所以 TCP 协议传输数据的整个过程就如下图所示:

         在正式进行数据传输之前,需要先建立连接,当成功建立 TCP 连接之后,双方就可以进行数据传输了。 当不再需要传输数据时,关闭连接即可!

TCP 状态说明

        TCP 协议在建立连接、断开连接以及数据传输过程中都会呈现出现不同的状态,不同的状态采取的动作也是不同的,需要处理各个状态之间的关系。对于上文中出现的一些状态标志,以及除了这些状态标志之外,其它的一些 TCP 状态,说明如下所示:

  • CLOSED 状态:表示一个初始状态。
  • LISTENING 状态:这是一个非常容易理解的状态,表示服务器端的某个 SOCKET 处于监听状态, 监听客户端的连接请求,可以接受连接了。譬如服务器能够提供某种服务,它会监听客户端 TCP 端口的连接请求,处于 LISTENING 状态,端口是开放的,等待被客户端连接。
  • SYN_SENT 状态(客户端状态):当客户端调用 connect()函数连接时,它首先会发送 SYN 报文给服务器请求建立连接,因此也随即它会进入到了 SYN_SENT 状态,并等待服务器的发送三次握手中的第 2 个报文。SYN_SENT 状态表示客户端已发送 SYN 报文。
  • SYN_REVD 状态(服务端状态):这个状态表示服务器接受到了 SYN 报文,在正常情况下,这个状 态是服务器端的 SOCKET 在建立 TCP 连接时的三次握手过程中的一个中间状态,很短暂,基本上用 netstat 你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次 TCP 握手过程中最后一个 ACK 报文不予发送。因此这种状态时,当收到客户端的 ACK 报文后,它会进入 到 ESTABLISHED 状态。
  • ESTABLISHED 状态:这个容易理解了,表示连接已经建立了。
  • FIN_WAIT_1 和 FIN_WAIT_2 状态:其实 FIN_WAIT_1 和 FIN_WAIT_2 状态的真正含义都是表示等待对方的 FIN 报文。而这两种状态的区别是:FIN_WAIT_1 状态实际上是当 SOCKET 在 ESTABLISHED 状态时,它想主动关闭连接,向对方发送了 FIN 报文,此时该 SOCKET 即进入到 FIN_WAIT_1 状态。而当对方回应 ACK 报文后,则进入到 FIN_WAIT_2 状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应 ACK 报文,所以 FIN_WAIT_1 状态一般是比较难见到的,而 FIN_WAIT_2 状态还有时可以用 netstat 看到。
  • TIME_WAIT 状态:表示收到了对方的 FIN 报文,并发送出了 ACK 报文,就等 2MSL 后即可回 到 CLOSED 可用状态了。如果 FIN_WAIT_1 状态下,收到了对方同时带 FIN 标志和 ACK 标志的报文时,可以直接进入到 TIME_WAIT 状态,而无须经过 FIN_WAIT_2 状态。
  • CLOSE_WAIT 状态:这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方 close 一个 SOCKET 后发送 FIN 报文给自己,你系统毫无疑问地会回应一个 ACK 报文给对方,此时则进入到 CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方, 如果没有的话,那么你也就可以 close 这个 SOCKET,发送 FIN 报文给对方,也即关闭连接。所以你在 CLOSE_WAIT 状态下,需要完成的事情是等待你去关闭连接。
  • LAST_ACK 状态:它是被动关闭一方在发送 FIN 报文后,最后等待对方的 ACK 报文。当收到 ACK 报文后,也即可以进入到 CLOSED 状态了。

        以上便是关于 TCP 状态的一些描述说明,状态之间的转换关系就如上图中所示。

UDP 协议

        除了 TCP 协议外,还有 UDP 协议,想必大家都听过说,UDP 是 User Datagram Protocol 的简称,中文 名是用户数据报协议,是一种无连接、不可靠的协议,同样它也是工作在传输层。它只是简单地实现从一端 主机到另一端主机的数据传输功能,这些数据通过 IP 层发送,在网络中传输,到达目标主机的顺序是无法 预知的,因此需要应用程序对这些数据进行排序处理,这就带来了很大的不方便,此外,UDP 协议更没有流量控制、拥塞控制等功能,在发送的一端,UDP 只是把上层应用的数据封装到 UDP 报文中,在差错检测 方面,仅仅是对数据进行了简单的校验,然后将其封装到 IP 数据报中发送出去。而在接收端,无论是否收 到数据,它都不会产生一个应答发送给源主机,并且如果接收到数据发送校验错误,那么接收端就会丢弃该 UDP 报文,也不会告诉源主机,这样子传输的数据是无法保障其准确性的,如果想要其准确性,那么就需 要应用程序来保障了。

        UDP 协议的特点:

        ①、无连接、不可靠;

        ②、尽可能提供交付数据服务,出现差错直接丢弃,无反馈;

        ③、面向报文,发送方的 UDP 拿到上层数据直接添加个 UDP 首部,然后进行校验后就递交给 IP 层, 而接收的一方在接收到 UDP 报文后简单进行校验,然后直接去除数据递交给上层应用;

        ④、速度快,因为 UDP 协议没有 TCP 协议的握手、确认、窗口、重传、拥塞控制等机制,UDP 是一个 无状态的传输协议,所以它在传递数据时非常快,即使在网络拥塞的时候 UDP 也不会降低发送的数据。

        UDP 虽然有很多缺点,但也有自己的优点,所以它也有很多的应用场合,因为在如今的网络环境下, UDP 协议传输出现错误的概率是很小的,并且它的实时性是非常好,常用于实时视频的传输,比如直播、 网络电话等,因为即使是出现了数据丢失的情况,导致视频卡帧,这也不是什么大不了的事情,所以,UDP 协议还是会被应用与对传输速度有要求,并且可以容忍出现差错的数据传输中。

端口号的概念

        前面给大家介绍了 IP 地址,互联网中的每一台主机都需要一个唯一的 IP 地址以标识自己的身份,网络中传输的数据包通过 IP 地址找到对应的目标主机;一台主机通常只有一个 IP 地址,但主机上运行的网络进程却通常不止一个,譬如 Windows 电脑上运行着 QQ、微信、钉钉、网页浏览器等,这些进程都需要进行网络连接,它们都可通过网络发送/接收数据,那么这里就有一个问题?主机接收到网络数据之后,如何确定该数据是哪个进程对应的接收数据呢?其实就是通常端口号来确定的。

        端口号本质上就是一个数字编号,用来在一台主机中唯一标识一个能上网(能够进行网络通信)的进程,端口号的取值范围为 0~65535。一台主机通常只有一个 IP 地址,但是可能有多个端口号,每个端口号表示一个能上网的进程。一台拥有 IP 地址的主机可以提供许多服务,比如 Web 服务、FTP 服务、SMTP 服务等,这些服务都是能够进行网络通信的进程,IP 地址只能区分网络中不同的主机,并不能区分主机中的这些进程,显然不能只靠 IP 地址,因此才有了端口号。通过“IP 地址+端口号”来区分主机不同的进程。 很多常见的服务器它都有特定的端口号,具体详情如下表所示:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/527306.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringSecurity安全权限框架及其原理

1. 基础使用 首先创建最基本的SpringBoot项目&#xff0c;默认都会。主要是引入依赖和创建Controller进行测试。 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://w…

十五天MySQL学习计划(运维篇-完结)读写分离-第十五天

十五天MySQL学习计划&#xff08;运维篇-完结&#xff09;读写分离-第十五天 读写分离 1.读写分离 ​ 读写分离&#xff0c;简单的说是把对数据库的读和写操作分开&#xff0c;以对应不同的数据库服务器。主服务器提供写操作&#xff0c;从数据库提供读操作&#xff0c;这样…

linux0.12-8-10-sys.c

[369页] 1、 这个文件需要配合其他文件一起看才能明白函数的作用&#xff1b; 2、 进程ID和进程组ID是描述进程之间的关系&#xff0c;与用户ID和组ID等其他无关系&#xff1b; 3、 用户ID和组ID和文件&#xff08;程序&#xff09;属性有关&#xff0c;当进程执行&#xff08;…

首发!车联网前装搭载率破70%,本土供应商抢下半壁江山

对于汽车智能化来说&#xff0c;网联化是相辅相成的角色&#xff0c;从传统3G、4G到5G的进化&#xff0c;提升座舱信息娱乐的体验&#xff1b;到C-V2X落地为辅助驾驶及自动驾驶提供冗余感知。 同时&#xff0c;车联网的普及&#xff0c;也进一步驱动互联网生态内容、服务以及类…

【AUTOSAR】【以太网】SoAd

目录 一、概述 二、限制与约束 三、依赖模块 5.1 TCPIP模块 5.2 通用上层 四、功能描述 4.1 套接字连接 4.2 PDU传输 4.3 PDU Header option 4.4 PDU 接收 4.5 最佳匹配算法 4.6 消息接受策略 4.7 TP PDU取消 4.8 路由组 4.9 PDU fan-out 五、API接口 5.1 API…

SpringBoot实现登录拦截的实现

对于管理系统或其他需要用户登录的系统&#xff0c;登录验证都是必不可少的环节&#xff0c;在SpringBoot开发的项目中&#xff0c;通过实现拦截器来实现用户登录拦截并验证。 1、SpringBoot实现登录拦截的原理 SpringBoot通过实现HandlerInterceptor接口实现拦截器&#xff…

如何完成GNSS接收器的定时校准

背景 GNSS以其提供亚米级精度定位的能力而闻名。然而鲜为人知的是&#xff0c;GNSS还提供了一种非常便捷的方法&#xff0c;可以通过GNSS接收器获得纳秒&#xff08;甚至亚纳秒&#xff09;的定时精度。事实上&#xff0c;除了三个空间维度之外&#xff0c;GNSS还使用户能够计…

iPhone照片导入电脑的图文教程,批量上传的3个方法!

案例&#xff1a;苹果手机照片怎么批量上传到电脑&#xff1f; 【友友们&#xff0c;手机照片太多&#xff0c;占用了我很多内存。想要把照片上传批量上传到电脑上进行保存&#xff0c;该怎么做&#xff1f;】 随着iPhone的普及和摄影功能的提升&#xff0c;越来越多的用户希望…

Rave Reports v2022 for Delphi 7-11

Rave Reports v2022 for Delphi 7-11 Rave Reports是来自Nevrona的一组公司&#xff0c;从Delphi和CBuilder中的数据库中报告进度。您可以使用专用工具轻松设计自己的报告。如果您需要将报告更改为您的用户&#xff0c;例如要发布的订单报告&#xff0c;此工具也提供了此功能&a…

Java | 一分钟掌握定时任务 | 3 - 单机定时之Timer

作者&#xff1a;Mars酱 声明&#xff1a;本文章由Mars酱原创&#xff0c;部分内容来源于网络&#xff0c;如有疑问请联系本人。 转载&#xff1a;欢迎转载&#xff0c;转载前先请联系我&#xff01; 介绍 这个是个JDK远古时代的api了&#xff0c;据考证&#xff0c;可以追溯到…

CSS小技巧之圆形虚线边框

虚线相信大家日常都用的比较多&#xff0c;常见的用法就是使用 border-style 控制不同的样式&#xff0c;比如设置如下边框代码&#xff1a; border-style: dotted dashed solid double;这将设置顶部的边框样式为点状&#xff0c;右边的边框样式为虚线&#xff0c;底部的边框样…

视频采集到录制 - 采集到显示碰到一些难点

项目中用到相机后端处理&#xff0c;走了一些弯路&#xff0c;也遇到不少问题&#xff08;解决了不少问题&#xff09;&#xff0c;特意写下本文记录下当时点点滴滴。 讲一下背景&#xff0c;公司自研相机&#xff0c;用于一些高端场合&#xff0c;因此对后端处理也非常讲究 …

网络基本知识分享

目录 1.IP地址 2.端口号 3.协议 4.协议分层 5.Tcp/Ip五层网络模型 5.1 应用层 5.2 传输层 5.3 网络层 5.4 数据链路层 5.5 物理层 6.封装和分用 6.1 封装 6.1.1 应用层拿到数据 6.1.2 向下传递给传输层 6.1.3 继续向下传递给网络层 6.1.4 继续向下传递给数据链…

【自制视频课程】C++OpnecV基础35讲——第一章 前言

为什么要学习OpenCV&#xff1f; 首先&#xff0c;opencv是一个广泛使用的计算机视觉库&#xff0c;它提供了丰富的图像处理和计算机视觉算法&#xff0c;可以帮助我们快速地开发出高质量的图像处理应用程序&#xff1b; 其次&#xff0c;opencv是一个开源库&#xff0c;可以免…

Spark大数据处理讲课笔记4.3 Spark SQL数据源 - Parquet文件

文章目录 零、本讲学习目标一、Parquet概述二、读取和写入Parquet的方法&#xff08;一&#xff09;利用parquet()方法读取parquet文件1、读取parquet文件2、显示数据帧内容 &#xff08;二&#xff09;利用parquet()方法写入parquet文件1、写入parquet文件2、查看生成的parque…

零入门kubernetes网络实战-32->基于路由技术+brigde+veth pair形成的跨主机通信方案

《零入门kubernetes网络实战》视频专栏地址 https://www.ixigua.com/7193641905282875942 本篇文章视频地址(稍后上传) 本文主要使用的技术是 路由技术Linux虚拟网桥虚拟网络设备veth pair来实现跨主机通信 该方案是flannel网络方案中的host-gw网络模型的基础。 1、总结 本…

化制为智,驭数前行 | 如何把握油气装备领域智能制造的未来?

01「智」赋未来&#xff0c;油燃而升 2015年&#xff0c;我国提出了“中国制造2025”规划&#xff0c;把智能制造作为两化深度融合的主攻方向&#xff0c;智能制造产业链所蕴藏的巨大投资机会将逐渐被市场挖掘。作为国家战略的基础&#xff0c;油气工程装备&#xff0c;特别是…

C++ 基础STL-list容器

STL-list 容器&#xff0c;又称双向链表容器&#xff0c;即该容器的底层是以双向链表的形式实现的。这意味着&#xff0c;list 容器中的元素可以分散存储在内存空间里&#xff0c;而不是必须存储在一整块连续的内存空间中。 链表的优点&#xff1a;可以对任意位置进行快速插入和…

【触觉智能分享】RK3568+Debian系统如何旋转屏幕显示方向

大家在购买开发板后&#xff0c;默认开机进入桌面屏幕显示方向是竖屏&#xff0c;有些用户想修改为横屏显示&#xff0c;本文就用IDO-EVB3568为例&#xff0c;用Debian系统演示如何旋转屏幕显示方向&#xff0c;此方法适用于所有RK356X系列产品。 IDO-EVB3568开发板拥有四核A5…

【数据结构】--- 几分钟走进栈和队列(详解-上)

文章目录 前言&#x1f31f;一、栈&#x1f30f;1.1栈的概念及结构&#xff1a;&#x1f30f;1.2实现栈的两种方式&#xff1a; &#x1f31f;二、栈实现(数组栈)&#x1f30f;2.1结构&#xff1a;&#x1f30f;2.2初始化&#xff1a;&#x1f4ab;2.2.1第一种代码&#xff1a;…