当前位置: 首页 > news >正文

TCP网络协议栈和Posix网络部分API总结

文章目录

  • Posix网络部分API综述
  • TCP协议栈通信过程
    • TCP三次握手和四次挥手(看下图)
      • 三次握手
        • 常见问题?
          • 为什么是三次握手而不是两次?
          • 三次握手和哪些函数有关?
          • TCP的生命周期是从什么时候开始的?
      • 四次挥手
      • 通信状态转换图
          • 由于数据包传输速率不同,client先收到了FIN,后收到ack,状态是如何转换的?
  • 核心步骤
    • 建立连接
      • socket函数
      • bind函数
      • listen函数
        • listen函数的backlog参数的作用
      • accept函数
      • connect函数
    • 数据传输
    • recv函数和send函数
    • 断开连接
      • close函数
        • 问题思考
          • 双方如果同时调用close函数会发生什么?
          • 同理双方同时调用了connect函数呢?(P2P模式会出现)

Posix网络部分API综述

  • 客户端:socket、bind(可以不绑定)、connect、send、recv、close
  • 服务端:socket、bind、listen、accept、recv、send、recv、close
  • 所有的语言进行网络通信,只要是基于linux底层都会去调用这道api。

TCP协议栈通信过程

TCP三次握手和四次挥手(看下图)

在这里插入图片描述

  • 参数解释:
    • seq:TCP头里的sequence,代表发送的TCP包的序列号。
    • ack:TCP头里的acknum,代表对上次接收到的TCP包的应答,通常是上次接收包的seq号+1。
    • SYN和ACK代表标志位。
    • syn和ack主要是实现了三个目的:
      1. 防止数据丢失,当我们发送出去的syn很久没有得到ack应答时,就会进行重传等操作。
      2. 防止数据重复,可能对方因为某些原因对一个请求发了很多次应答,可以依据这两个参数去防止数据重复接收。
      3. 防止数据乱序,这个很好理解就是根据seq和ack确保数据接收正确,因为网络包在网络上的传输速率不同,可能先发的包后面到。
    • 另外三次握手建立连接时,双方的第一个seq值是随机的。

三次握手

  1. 首先由通信双方的某一方(后面就用client了,其实server和client都是可以的)发起连接请求,即发送一个带SYN标志位的TCP数据包给server端。
  2. server端收到数据包后,除了SYN位以外,还会增加一个ACK确认位,然后发送给clinet端。
  3. client端收到数据包后,给server端回复一个带ACK确认位的数据包给服务端,到此,通信双方就算建立连接了。
常见问题?
为什么是三次握手而不是两次?
- 因为TCP连接是安全可靠的,三次握手的话会保证双方都能接受到对方的数据,第一次服务端收到客户端消息后可以确定客户端发送数据没问题,然后第二次服务端发送给客户端消息,客户端可以确定服务端的收发都没有问题,但是服务端不知道客户端接收是否成功,所以,客户端还需要发一个数据包告诉服务端,它的接收也没有问题,因此,这里是三次连接而不是两次。
三次握手和哪些函数有关?
  • 首先肯定是connect函数,调用后会发生第一次握手。
  • listen函数调用后TCP协议栈会去监听client请求,收到第一次握手后会向对方发送数据包,这是第二次握手,此时这个连接就被放入半连接队列里了。
  • 至于第三次握手是TCP协议栈完成的(其实第二次也是),收到第三次握手的数据包后,会从半连接队列里校验,校验成功后将其从半连接队列里mv到全连接队列。
TCP的生命周期是从什么时候开始的?
  • 从connect调用后就开始了。

四次挥手

  1. 第一次挥手,是主动断开连接的一方,发送带有FIN和ACK标志位的TCP包。
  2. 第二次是被动断开连接一方在收到数据包后,立马回应一个ACK标志位的TCP包,告诉对方我收到了对方的包,但是数据还没有处理完成,还有些工作要处理。
  3. 第三次依然是被动断开连接一方在数据处理完成之后,会给对方发送FIN和ACK标志位的TCP包,告诉对方我数据处理完了,你可以关闭连接了。
  4. 第四次挥手,是主动断开方发送ACK标志位的TCP包,然后被动断开方就关闭连接了。

通信状态转换图

在这里插入图片描述

  • 建立连接:
    • 服务端:
      1. 初始状态为closed状态,调用listen函数后进入LISTEN状态。
      2. 收到SYN标志位的TCP包,并向对方发送SYN和ACK标志位的TCP包后,变为SYN_RCVD状态。
      3. 收到对方带ACK标志位的包后变为ESTABLISTED状态,至此连接建立。(这里不是accept去完成三次握手的,三次握手由TCP协议栈完成,accept只是堵塞获取客户端信息的)。
    • 客户端:
      1. 初始状态为closed状态,调用connect函数,发送SYN标志位的TCP包后进入SYN_SENT状态。
      2. 由TCP协议栈完成后续的握手环节,当connect函数成功返回后,直接进入ESTABLISTED状态。
  • 断开连接:断开连接一般情况下可以是任意一方发起,这里以客户端主动断开为例
    • 服务端:
      1. 当客户端主动断开连接后,服务端收到FIN位的TCP包,此时服务端的协议栈会立刻发送给对方一个ACK确认位,此时服务端酒进入了CLOSED_WAIT状态。
      2. 此时recv函数会继续去处理数据,当读到数据长度为0,并且数据全部处理完后,服务端主动调用close函数关闭通信fd,这时服务端会给客户端发送FIN标志位的TCP包,然后服务端进入LAST_ACK状态。
      3. 当服务端收到客户端的ACK标志位的包后,服务端由LAST_ACK转变为CLOSED状态。
    • 客户端:
      1. 客户端主动调用closed函数关闭fd,那么TCP协议栈会给服务端发送一个带SYN标志位的TCP包,此后客户端进入FIN_WAIT1状态。
      2. 当收到服务端带ACK标志位的TCP包后,由FIN_WAIT1转变为FIN_WAIT2状态。
      3. 当收到服务端带FIN标志位的TCP包,并向服务端发送ACK标志位的TCP包后就进入了TIME_WAIT状态,该状态会持续2MSL,(MSL为网络包在网络中的最大存活时间。),当2MSL到达后,转换为CLOSED状态。
  • 注意:
    • TCP的状态转换是由TCP协议栈管理的,不是由代码管理。
由于数据包传输速率不同,client先收到了FIN,后收到ack,状态是如何转换的?
  • 就是上图的由FIN_WAIT1状态直接到了CLOSING状态,然后等收到了ack后再转换为TIME_WAIT。

核心步骤

建立连接

socket函数

  • socket函数做了两件事情:
    1. 分配一个fd用来监听连接,这里是采用bit_map的算法分配fd,当对应fd位为0时就可以分配。
    2. 创建一个TCP控制块TCB。

bind函数

  • 其实bind函数就做了一个操作,将ip和port设置到TCP控制块里的src ip和port。

listen函数

  • listen函数就像一个开关,如果不调用listen函数的话,是没有办法进行三次握手的。
  • listen函数也做了两个事情:
    1. 将tcb里的status设置为LISTEN状态。
    2. 为tcb分配分配一个全连接队列和半连接队列。(全连接队列指的是已经完成三次握手的,半连接队列指还没有完成三次握手的)
listen函数的backlog参数的作用
  • 起初主要是为了防止syn(第一次握手)泄洪,但是现在一般有堡垒机和防火墙,这个参数不常用了。
  • listen函数的backlog参数从70年代发展到现在大概有三个版本:
    1. 指的是半连接队列的长度。
    2. 半连接+全连接队列的长度。
    3. 全连接队列的长度。(如今的版本)

accept函数

  • accept函数做了两件事情:
    1. 为该连接分配一个fd
    2. 将fd绑定到从全连接队列取出来的连接tcb上,这个用于通信的tcb是个五元组(src ip和port,dst ip和port,传输协议)和读写缓冲区。
  • 注意:若listen的sockfd被设置为ET模式,那么需要循环调用accept去获取fd。

connect函数

  • 向对方发送带SYN标志的数据包,请求连接。

数据传输

recv函数和send函数

  • 这两个函数是将数据从TCP缓冲区读到用户buffer里以及将用户数据写到TCP缓冲区里,而不是直接端到端的同步通信,这里是异步的,数据什么时候从缓冲区发出去,怎么发和send没有关系

断开连接

close函数

  • close函数通信双方都可以调用,也做了两个事情:
    1. 关闭fd。
    2. 告诉TCP协议栈,向对方发送一个带FIN标志位的数据包。
  • server调用recv返回值为0的时候,就意味着收到了对方的FIN数据包,且TCP协议栈自动向对方发送ACK确认。(第一次挥手)此时server也可以调用close函数去关闭fd,然后server会向对方也发送带FIN的数据包。
问题思考
双方如果同时调用close函数会发生什么?
  • 首先双方都向对方发送FIN数据包,然后双方收到后,都向对方发送ACK确认,然后双方又向对方发送FIN,最后双方都收到了对方的ack,此时双方都产生了time_wait状态。(服务器一般情况下不要去调用close函数,减少time_wait状态出现)
同理双方同时调用了connect函数呢?(P2P模式会出现)

相关文章:

TCP网络协议栈和Posix网络部分API总结

文章目录 Posix网络部分API综述TCP协议栈通信过程TCP三次握手和四次挥手(看下图)三次握手常见问题?为什么是三次握手而不是两次?三次握手和哪些函数有关?TCP的生命周期是从什么时候开始的? 四次挥手通信状态…...

《解释器模式(极简c++)》

本文章属于专栏- 概述 - 《设计模式(极简c版)》-CSDN博客 模式说明 方案: 对每个data建立一个单点解释器对象X,dataA和dataB之间的关系,建立一个关系解释器对象Y,这里的Y处理的是X1和X2。这样,…...

c#仿ppt案例

画曲线 namespace ppt2024 {public partial class Form1 : Form{public Form1(){InitializeComponent();}//存放所有点的位置信息List<Point> lstPosition new List<Point>();//控制开始画的时机bool isDrawing false;//鼠标点击开始画private void Form1_MouseD…...

10.图像高斯滤波的原理与FPGA实现思路

1.概念 高斯分布 图像滤波之高斯滤波介绍 图像处理算法|高斯滤波   高斯滤波(Gaussian filter)包含很多种&#xff0c;包括低通、高通、带通等&#xff0c;在图像上说的高斯滤波通常是指的高斯模糊(Gaussian Blur)&#xff0c;是一种高斯低通滤波。通常这个算法也可以用来模…...

WebGIS 地铁交通线网 | 图扑数字孪生

数字孪生技术在地铁线网的管理和运维中的应用是一个前沿且迅速发展的领域。随着物联网、大数据、云计算以及人工智能技术的发展&#xff0c;地铁线网数字孪生在智能交通和智慧城市建设中的作用日益凸显。 图扑软件基于 HTML5 的 2D、3D 图形渲染引擎&#xff0c;结合 GIS 地图…...

Docker 哲学 - push 本机镜像 到 dockerhub

注意事项&#xff1a; 1、 登录 docker 账号 docker login 2、docker images 查看本地镜像 3、注意的是 push镜像时 镜像的tag 需要与 dockerhub的用户名保持一致 eg&#xff1a;本地镜像 express:1 直接 docker push express:1 无法成功 原因docker不能识别 push到哪里 …...

大数据学习第十二天(hadoop概念)

1、服务器之间数据文件传递 1&#xff09;服务器之间传递数据&#xff0c;依赖ssh协议 2&#xff09;http协议是web网站之间的通讯协议&#xff0c;用户可已通过http网址访问到对应网站数据 3&#xff09;ssh协议是服务器之间&#xff0c;或windos和服务器之间传递的数据的协议…...

管理科学笔记

1.线性规划 画出区域&#xff0c;代入点计算最大最小值 2.最小生成树 a.断线法&#xff0c;从大的开始断 b.选择法&#xff0c;从小的开始选 3.匈牙利法 维度数量直线覆盖所有的0 4.一直选最当前路线最短路径 5.线性规划 6.决策论...

WebKit结构简介

WebKit是一款开源的浏览器引擎&#xff0c;用于渲染网页内容。它负责将HTML、CSS和JavaScript等网络资源转换为用户在屏幕上看到的图形界面。WebKit是一个跨平台的引擎&#xff0c;可以在多种操作系统上运行&#xff0c;如Windows、macOS、Linux等。 以下是一篇关于WebKit结构…...

Kaggle:收入分类

先看一下数据的统计信息 import pandas as pd # 加载数据&#xff08;保留原路径&#xff0c;但在实际应用中建议使用相对路径或环境变量&#xff09; data pd.read_csv(r"C:\Users\11794\Desktop\收入分类\training.csv", encodingutf-8, encoding_errorsrepl…...

【Go】十七、进程、线程、协程

文章目录 1、进程、线程2、协程3、主死从随4、启动多个协程5、使用WaitGroup控制协程退出6、多协程操作同一个数据7、互斥锁8、读写锁9、deferrecover优化多协程 1、进程、线程 进程作为资源分配的单位&#xff0c;在内存中会为每个进程分配不同的内存区域 一个进程下面有多个…...

深入剖析JavaScript中的this(上)

在Javascript中&#xff0c;this 关键字是一个非常重要的概念&#xff0c;this这个关键字可以说是很常见也用的很多&#xff0c;说它简单也很简单&#xff0c;说它难也很难。我们经常会用到this&#xff0c;也经常会因为this头疼&#xff0c;是一个经常被误解和误用的概念&…...

Junit深入讲解(JAVA单元测试框架)

1、此处用的是Junit5&#xff0c;此处pom文件需要引的依赖是 <dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.9.1</version><scope>test</scope></depende…...

Spring boot如何执行单元测试?

Spring Boot 提供了丰富的测试功能&#xff0c;主要由以下两个模块组成&#xff1a; spring-boot-test&#xff1a;提供测试核心功能。spring-boot-test-autoconfigure&#xff1a;提供对测试的自动配置。 Spring Boot 提供了一个 spring-boot-starter-test一站式启动器&…...

Django详细教程(一) - 基本操作

文章目录 前言一、安装Django二、创建项目1.终端创建项目2.Pycharm创建项目&#xff08;专业版才可以&#xff09;3.默认文件介绍 三、创建app1.app介绍2.默认文件介绍 四、快速上手1.写一个网页步骤1&#xff1a;注册app 【settings.py】步骤2&#xff1a;编写URL和视图函数对…...

Qt编译QScintilla(C++版)过程记录,报错-lqscintilla2_qt5d、libqscintilla2_qt5找不到问题解决

Qt编译QScintilla [C版] 过程记录 本文是编译该 QScintilla 组件库供 QtCreater 开发 C 桌面软件 流程记录一、编译环境 系统&#xff1a; Windows 10Qt&#xff1a;Qt 5.14.2编译套件&#xff1a;MinGW 64Qscintilla&#xff1a;QScintilla_src-2.11.6 二、下载链接 网站链…...

android QtScrcpy 共享屏幕 获取本地Address

android QtScrcpy https://gitee.com/B arryda/QtScrcpy scrcpy - 手机无线投屏到电脑 https://zhuanlan.zhihu.com/p/80264357?utm_sourcewechat_session public String getLocalIpAddress() { String ipv4; List<NetworkInterface> nilist …...

【SQL Server】1. 认识+使用

1. 创建数据库的默认存储路径 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft SQL Server 2008 R2 当我们选择删除数据库时&#xff0c;对应路径下的文件也就删除了 2. 导入导出数据工具的路径 3. 注册数据库遇到的问题 ??? 目前的问题就是服务器新建…...

视频汇聚/安防监控/视频存储EasyCVR平台EasyPlayer播放器更新:新增【性能面板】

视频汇聚/安防监控/视频存储平台EasyCVR基于云边端架构&#xff0c;可以在复杂的网络环境中快速、灵活部署&#xff0c;平台视频能力丰富&#xff0c;可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云…...

图神经网络实战(7)——图卷积网络(Graph Convolutional Network, GCN)详解与实现

图神经网络实战&#xff08;7&#xff09;——图卷积网络详解与实现 0. 前言1. 图卷积层2. 比较 GCN 和 GNN2.1 数据集分析2.2 实现 GCN 架构 小结系列链接 0. 前言 图卷积网络 (Graph Convolutional Network, GCN) 架构由 Kipf 和 Welling 于 2017 年提出&#xff0c;其理念是…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...