网络编程套接字( TCP协议通讯流程)
目录
1、绑定失败问题
2、TCP协议通讯流程
三次握手的过程
数据传输的过程
四次挥手的过程
TCP和UDP对比
1、绑定失败问题
当我们测试网络代码时,先将服务端绑定8080端口运行,然后运行客户端,并让客户端连接当前服务器:
当有客户端连接的情况下,我直接将服务端关闭,此时服务端想要再次绑定8080端口时,就会绑定失败:
综上:如果server在保有连接的时候,server自己先因为一些原因而导致退出,服务器无法立即重启。具体原因等后续博主讲解TCP协议时再详谈。
2、TCP协议通讯流程
下图是基于TCP协议的客户端 / 服务器程序的一般流程:
- TCP是面向连接的,client 通信前先 connect;server 通信前先 accept
- TCP在建立连接的时候,采用的是三次握手,在断开连接的时候,采用的是四次挥手
- connect发起三次挥手(client),connect只有客户端做。close客户端和服务端都要做。close() client && close() server -> close() 执行4次挥手中的2次
下面我们结合TCP协议的通信流程,来初步认识一下三次握手和四次挥手,以及建立连接和断开连接与各个网络接口之间的对应关系。
三次握手的过程
采用三次握手来建立连接。三次握手的过程就是两台主机建立通信连接的过程。软件服务器架构:客户端(左),服务端(右)
- 第一次,客户端给服务端发送SYN码,请求连接。
- 第二次,服务端收到客户端发来的请求,然后表示可以连接,发送SYN+ACK。
- 第三次,客户端收到服务器的确认,并再次向服务器发送 ACK码表示确认,服务器收到,两台主机建立连接完成。
示例:
- 偶然的一次机遇,你(客户端)遇到了多年未见的老同学(服务端)。因为变化太大,你只是觉着像,但还是像她微笑点了点头(第一次)。老同学看到了你,一眼就认出了你,也对你微笑点了点头并挥了挥手(第二次)。你看到老同学的反应,更加坚定你们认识。随后,你也向老同学挥了挥手(第三次)。在这个例子中微笑点头用SYN表示,挥挥手用ACK表示。
初始化服务器
- 当服务器完成套接字创建、绑定以及监听的初始化动作之后,就可以调用accept函数阻塞等待客户端发起请求连接了。
服务器初始化:
- 调用socket,创建文件描述符。
- 调用bind,将当前的文件描述符和IP/PORT绑定在一起,如果这个端口已经被其他进程占用了,就会bind失败。
- 调用listen,声明当前这个文件描述符作为一个服务器的文件描述符,为后面的accept做好准备。
- 调用accept,并阻塞,等待客户端连接到来。
建立连接
- 而客户端在完成套接字创建后,就会在合适的时候通过connect函数向服务器发起连接请求,而客户端在connect的时候本质是通过某种方式向服务器三次握手,因此connect的作用实际就是触发三次握手。
建立连接的过程:
- 调用socket,创建文件描述符。
- 调用connect,向服务器发起连接请求。
- connect会发出SYN段并阻塞等待服务器应答(第一次)。
- 服务器收到客户端的SYN,会应答一个SYN-ACK段表示“同意建立连接”(第二次)。
- 客户端收到SYN-ACK后会从connect返回,同时应答一个ACK段(第三次)。
这个建立连接的过程,通常称为三次握手。
- 需要注意的是,连接并不是立马建立成功的,由于TCP属于传输层协议,因此在建立连接时双方的操作系统会自主进行三次协商,最后连接才会建立成功。
数据传输的过程
- 连接一旦建立成功并且被accept获取上来后,此时客户端和服务器就可以进行数据交互了。需要注意的是,连接建立和连接被拿到用户层是两码事,accept函数实际不参与三次握手这个过程,因为三次握手本身就是底层TCP所做的工作。accept要做的只是将底层已经建立好的连接拿到用户层,如果底层没有建立好的连接,那么accept函数就会阻塞住直到有建立好的连接。
- 而双方在进行数据交互时使用的实际就是read和write,其中write就叫做写数据,read就叫做读数据。write的任务就是把用户数据拷贝到操作系统,而拷贝过去的数据何时发以及发多少,就是由TCP决定的。而read的任务就是把数据从内核读到用户。
数据传输的过程
- 建立连接后,TCP协议提供全双工的通信服务,所谓全双工的意思是,在同一条连接中,同一时刻,通信双方可以同时写数据,相对的概念叫做半双工,同一条连接在同一时刻,只能由一方来写数据。
- 服务器从accept返回后立刻调用read,读socket就像读管道一样,如果没有数据到达就阻塞等待。
- 这时客户端调用write发送请求给服务器,服务器收到后从read返回,对客户端的请求进行处理,在此期间客户端调用read阻塞等待服务器端应答。
- 服务器调用write将处理的结果发回给客户端,再次调用read阻塞等待下一条请求。
- 客户端收到后从read返回,发送下一条请求,如此循环下去。
四次挥手的过程
四次挥手的过程就是两台主机断开通信连接的过程。软件服务器架构:客户端(左),服务端(右)
- 第一次,客户端发送FIN给服务端,表达要断开连接,现在是请求断开的状态
- 第二次,服务端收到FIN请求,回复ACK表达可以,等待结束的状态
- 第三次,服务端发送FIN给客户端,并且客户端收到ACK请求,进入半连接半断开状态
- 第四次,客户端收到FIN,等待时间,回复ACK确认,双方进入close状态
示例:
- 当你成功追到了女孩并走上婚姻的殿堂。结婚后你整体游手好闲,女生受不了你不思进取。便要提出和你离婚(第一次),你同意了她的离婚请求(第二次)。但同意归同意,离婚协议书上你死皮赖脸就是不签字,一直耗着女生。终于有一天,你也无法忍受这样耗下去了,便向她也提出了离婚申请(第三次)。女方果断答应(第四次)。此时双方进入CLOSE状态。
端口连接
- 当双方通信结束之后,需要通过四次挥手的方案使双方断开连接,当客户端调用close关闭连接后,服务器最终也会关闭对应的连接。而其中一次close就对应两次挥手,因此一对close最终对应的就是四次挥手。
断开连接的过程
- 如果客户端没有更多的请求了,就调用close关闭连接,客户端会向服务器发送FIN段(第一次)。
- 此时服务器收到FIN后,会回应一个ACK,同时read会返回0(第二次)。
- read返回之后,服务器就知道客户端关闭了连接,也调用close关闭连接,这个时候服务器会向客户端发送一个FIN(第三次)。
- 客户端收到FIN,再返回一个ACK给服务器(第四次)。
这个断开连接的过程,通常称为四次挥手。
注意通讯流程与socket API之间的对应关系
在学习socket API时要注意应用程序和TCP协议是如何交互的:
- 应用程序调用某个socket函数时TCP协议层完成什么动作,比如调用connect会发出SYN段。
- 应用程序如何知道TCP协议层的状态变化,比如从某个阻塞的socket函数返回就表明TCP协议收到了某些段,再比如read返回0就表明收到了FIN段。
为什么要断开连接?
- 建立连接本质上是为了保证通信双方都有专属的连接,这样我们就可以加入很多的传输策略,从而保证数据传输的可靠性。但如果双方通信结束后不断开对应的连接,那么系统的资源就会越来越少。
- 因为服务器是会收到大量连接的,操作系统必须要对这些连接进行管理,在管理连接时我们需要“先描述再组织”。因此当一个连接建立后,在服务端就会为该连接维护对应的数据结构,并且会将这些连接的数据结构组织起来,此时操作系统对连接的管理就变成了对链表的增删查改。
- 如果一个连接建立后不断开,那么操作系统就需要一直为其维护对应的数据结构,而维护这个数据结构是需要花费时间和空间的,因此当双方通信结束后就应该将这个连接断开,避免系统资源的浪费,这其实就是TCP比UDP更复杂的原因之一,因为TCP需要对连接进行管理。
TCP和UDP对比
- 可靠传输 vs 不可靠传输
- 有连接 vs 无连接
- 字节流 vs 数据报
相关文章:
网络编程套接字( TCP协议通讯流程)
目录 1、绑定失败问题 2、TCP协议通讯流程 三次握手的过程 数据传输的过程 四次挥手的过程 TCP和UDP对比 1、绑定失败问题 当我们测试网络代码时,先将服务端绑定8080端口运行,然后运行客户端,并让客户端连接当前服务器: 当有客户…...
WPF毛笔字实现过程
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
MHA实现mysql数据库高可用
目录 MHA原理 MHA工具包 MHA实现mysql高可用实战 MHA原理 ①MHA利用 SELECT 1 As Value 指令判断master服务器的健康性,一旦master 宕机,MHA 从宕机崩溃的master保存二进制日志事件(binlog events) ②识别含有最新更新的slave ③应用差异的中继日志&…...
leetcode每日一题:55. 跳跃游戏
系列:贪心算法 语言:java 题目来源:Leetcode55. 跳跃游戏 题目 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标。 示例 1: 输…...
【C++】map 和 set
文章目录一、关联式容器与键值对1、关联式容器2、键值对 pair3、树形结构的关联式容器二、set1、set 的介绍2、set 的使用三、multiset四、map1、map 的介绍2、map 的使用五、multimap一、关联式容器与键值对 1、关联式容器 在C初阶的时候,我们已经接触了 STL 中的…...
基于SpringBoot的酒店管理系统
系统环境 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:eclipse/myeclipse/i…...
JAVA框架知识整理
框架知识整理 SpringBoot、SpringMVC、Spring的区别和他们的作用? SpringBoot是一个微服务框架,其简化了Spring应用的创建、运行、测试、部署。使开发人员无需过多的关注XML配置。里面整合了许多框架例如SpringMVC、Spring Security和Spring Data JPA。…...
运算放大器:电压比较器
目录一、单限电压比较器二、滞回电压比较器三、窗口电压比较器最近在学习电机控制,遇到了与运算放大电路相关的知识,然而太久没有接触模拟电路,对该知识已经淡忘了,及时温故而知新,做好笔记,若有错误、不足…...
Linux的基础知识
根目录和家目录根目录:是Linux中最底层的目录,用"/"表示家目录:当前用户所在的路径,用“~”表示,root用户的家目录和普通用户的家目录不一样,普通用户的家目录在/home路径下,每一个用…...
【JavaEE】 IntelliJ IDEA 2022.2最新版Tomcat导入依赖详细教程全解及创建第一个Servlet程序
目录 一、软件资源 二、放置settings.xml文件 三、创建项目 四、引入依赖 五、创建目录 六、编写代码 写在前面:☞What is Servlet? Servlet其实是一种实现动态页面的技术。是一组由Tomcat提供给程序员的API(应用程序编程接口)…...
常见的卷积神经网络结构——分类、检测和分割
本文持续更新~~ 本文整理了近些年来常见的卷积神经网络结构,涵盖了计算机视觉领域的几大基本任务:分类任务、检测任务和分割任务。对于较复杂的网络,本文只会记录其中的核心模块以及重要的网络设计思想,并不会记录完整的网络结构。…...
20230323英语学习
Why Can You “Hear the Ocean” in Seashells? 为啥能在贝壳里“听见海的声音”? We’re told a number of stories as kids. One of the more harmless of these little lies is the one about seashells.You know the one: hold up a seashell to your ear, an…...
【粉丝投稿】上海某大厂的面试题,岗位是测开(25K*16)
简单介绍一句,大专出身,三年经验。跳了四次槽,面试了无数次,现在把自己的面试经验整理出来分享给大家,堪称必杀技! 1,一切从实际出发,对实际工作进行适当修饰 2,不会的简…...
shell简单使用介绍
脚本的基本元素声明,在解释并执行当前脚本文件中的语句之前,需要声明使用的命令解释器#一般写的解释器为 #!/bin/bash这里的#不再是注释了,而是必要的声明命令,也就是需要执行的语句注释,对代码进行解释说明分为单行注…...
RK3568平台开发系列讲解(调试篇)内核函数调用堆栈打印方法汇总
🚀返回专栏总目录 文章目录 一、dump_stack 函数二、WARN_ON(condition)函数三、BUG_ON (condition)函数四、panic (fmt...)函数沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将对驱动调试方法进行汇总学习。 一、dump_stack 函数 dump_stack 作用:打印内核调…...
一次内存泄露排查
前因: 因为测试 长时间压测导致 接口反应越来越慢,甚至 导致服务器 崩溃 排查过程 1、top 查看是 哪个进程 占用 内存过高 2、根据 进程 id 去查找 具体是哪个 程序的问题 ps -ef| grep 41356 可以看到 具体的 容器位置 排查该进程 对象存活 状态…...
「Mac安装ps」Adobo Photoshop 2023 下载安装详情教程,支持 AI 插件的 24 版 Photoshop
前言 Adobo Photoshop 2023 已推出,由于目前AI人工智能技术火爆,而很多的 AI 插件最低也需要24版的 photoshop ,所以这里我遍搜集并整理了此新版本的 photoshop 安装使用教程,后续也将提供 AI 插件的下载安装教程 安装文件下载 …...
Redis单线程还是多线程?IO多路复用原理
目录专栏导读一、Redis版本迭代二、Redis4.0之前为什么一直采用单线程?三、Redis6.0引入多线程四、Redis主线程和IO线程是如何完成请求的?1、服务端和客户端建立socket连接2、IO线程读取并解析请求3、主线程执行请求命令4、IO线程会写回socket和主线程清…...
小菜鸟Python历险记:(第五集)
今天写的文章是记录我从零开始学习Python的全过程。在Python中对方法进行备注的时候,往往都是写在方法中的第一行所在位置。在书写注释以后,在调用方法的时候,鼠标点击方法会有一个浮动的提示显示备注内容。具体如下图所示:注释的…...
【思维模型】五分钟了解<复利思维>,为何学习复利思维?什么是复利思维?如何应用复利思维?
【思维模型】五分钟了解<复利思维>,为何学习复利思维?什么是复利思维?如何应用复利思维?1. 为何学习复利思维?2. 什么是复利思维?3. 如何应用复利思维?4. 小结参考&#…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...





