posix API与网络协议栈

news2024/11/15 20:46:15

posix API与网络协议栈

scoket

socket包含两部分:fd、tcb(tcp control block)

其中,fd属于文件系统,可在用户态进行操控;而tcb属于内核协议栈

三次握手

20230117220414

服务端API

  1. socekt():创建一个tcb和fd(会将socketfd转换为listenfd)
    • fd最小为3,因为0、1、2号fd分别被stdin、stdout、stderr占了
    • 一个连接包括客户端socket和服务端socket,每个socket包括一个fd和一个tcb
  2. bind(): 为tcb绑定ip和端口
    • 两个特殊ip:0.0.0.0和127.0.0.1
    • 绑定0.0.0.0:socekt绑定多张网卡 (一张网卡一个ip,一个机器可能有多个网卡)
    • 绑定127.0.0.1:本地ip才能连接
  3. listen():指定全连接队列(或全连接+半连接队列的长度),把tcb 置为 listen 的状态。当客户端发送SYN包准备建立连接,服务端会init/add new tcb作为一个新的节点push in syn队列,此时服务端的状态由LISTEN转为SYN_RCVD, 并且服务端会发送SYN + ACK给客户端
  4. accept():当收到客户端的ACK后,此时会把syn队列中的tcb节点pop出来,再push in accept队列中,服务端状态由SYN_RCVD转为ESTABLISHED,三次握手完成。后续数据传输会从accept队列中取出tcb节点进行数据传输。并且accept为每个节点分配一个socket(conn_fd)
  5. recv/read(): 从读缓冲区读数据
  6. send/write(): 往写缓冲区写数据
  7. close(): 将FIN置为1,发送空包给对方请求关闭连接

客户端API

  1. socket():创建client_fd
  2. bind(): 可选,非必须
  3. connect():发起三次握手,若client_fd是阻塞的,则等待连接完成后返回;若client_fd是非阻塞的,则立即返回,如果连接成功,则返回可读/可写结果
  4. recv/read(): 从读缓冲区读数据
  5. send/write(): 往写缓冲区写数据
  6. close(): 将FIN置为1,发送空包给对方请求关闭连接

api小总结:

  1. socket和bind()都是本地操作
  2. listen()和accept()参与了三次握手,全连接和半连接队列示意图:
20230117221535
  1. 服务器的tcb通过bind()绑定本地(ip+port)、通过connect知道客户端(ip+port)

send相关问题

首先需注意不能通过send()>0来判断数据发送方成功了,因为send()只负责写协议栈,不负责发送数据。

无法send的情况

  1. 本地sendbuff满了
  2. 对方recvbuff空间不足,无法接收发送端的数据,此时内核协议栈会保留一个push的标志位,当有足够空间时,推给发送方进行发送

多次send时的粘包问题

比如我一次向sendbuff写1k的数据,共发送三次,但协议栈每次发送1.5k的数据,两次就发完了,就导致发送方发送了三次,但接收方只接收了两次,产生粘包现象

解决方法:

  • 包的协议头加包长度
  • 包尾加分隔符,如http就是加\r\n\r\n作为包结束标志

然而,这两种方法实现的前提都要求包是顺序到达的,就是说不能有中间包丢失,对此,tcp有一种延迟ack的超时重传机制:比如有序列号为1,2,3,4,5的5个包需要发送,接收端设置一个定时器(如设置200ms),每接收到一个包,就将定时器重置,当定时器到期后,发送ACK消息。

接收端:2包到达,重置定时器;1包到达,重置定时器;5包到达,重置定时器;3包到达,重复定时器;然后定时器过期,发送对2包的确认,也就是需要重传3,4,5包(乱序到达,接收方有重排机制恢复原有顺序)

这种延迟ack的方法有两个不好的点:

  • 实时性差:确认事件长,所以游戏都用UDP
  • 重传多,占用宽带:需要重传丢包以后的后续包,所以下载用UDP快
    不过这种延迟ACK是可以关闭的,也有算法对次提出了改进,利用NACK只需要重传丢失的包即可

四次挥手

挥手只分主动方和被动方

20230118192429

五个状态:

  1. 主动方调用close(),发送一个fin为1的空包,然后进入fin_wait 1状态
  2. 被动方recv()返回0,发送对这个包的确认,进入close_wait()状态
    • 如果服务器出现大量的fin_wait_2,说明服务器没及时close(),因为业务逻辑太多了,服务器需要很长时间去处理
    • 解决办法:要么先close()再处理业务逻辑;要么将这些数据放到一个队列,交给线程池去处理(应用层和传输层解耦)。
  3. 主动方接收到ack,进入fin_wait_2状态
  4. 被动方调用close(),进入last_ack状态
  5. 主动方recv()返回0,发送对这个包的确认,进入time_wait状态
    • 这个状态会维持2MSL,因为怕这个ack丢失了,被动方会超时重传fin包,但由于主动方关闭连接了,一直无法响应,那服务器就一直关闭不了

close后的socket回收:

  • 被动方:发送fin包:fd被回收;收到ack包:tcb被回收
  • 主动方:发送fin包:fd被回收;time_wait到期:tcb被回收

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

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

相关文章

Linux常用命令——tput命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) tput 通过terminfo数据库对终端会话进行初始化和操作 补充说明 tput命令将通过 terminfo 数据库对您的终端会话进行初始化和操作。通过使用 tput,您可以更改几项终端功能,如移动或更改光…

关系数据库-2-[mysql8]python3操作mysql

参考文档Python-PyMysql详解 参考文档使用pandas操作MySQL数据库 1 pymysql操作mysql PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库。 PyMySQL 遵循 Python 数据库 API v2.0 规范,并包含了 pure-Python MySQL 客户端库。 pip install PyMySQL1.…

在线教育-谷粒学院学习笔记(八)

文章目录1 内容介绍2 微服务3 微服务实现删除nacos4 删除课程-删除视频5 Hystrix1 内容介绍 Spring Colud 删除小节-删除视频删除课程-删除视频 2 微服务 service 三个服务 service_edu 8001service_oss 8002service_vod 8003 微服务 微服务是架构风格把一个项目拆分成多个…

NUMA介绍

早期CPU访问内存结构 UMA1(Uniform Memory Access, 一致性内存访问 ) 早期的计算机,内存控制器还没有整合进 CPU,所有的内存访问都需要经过北桥芯片来完成。 在 UMA 架构下,CPU 和内存之间的通信全部都要通过前端总线…

【Java|golang】2293. 极大极小游戏

给你一个下标从 0 开始的整数数组 nums ,其长度是 2 的幂。 对 nums 执行下述算法: 设 n 等于 nums 的长度,如果 n 1 ,终止 算法过程。否则,创建 一个新的整数数组 newNums ,新数组长度为 n / 2 &#x…

go语言初识——数据类型

目录 go go与C语言区别 helloworld 数据类型 变量 定义 类型推导 简短声明 : 匿名变量 常量 iota 基本类型 指针 数组 结构体 go Go是2009年开源的编程语言,Go语言具有以下特性:语法简洁、并发编程、编译迅速、数组安全、丰富的内置类型…

如何在 Antd Pro 框架上实现样式自定义?

文章目录一、前言二、实操过程一、前言 Ant Design Pro 是一个企业级中后台前端/设计解决方案,已经有完善的 UI 组件及设计风格,在一些特定项目中,往往涉及到对其调整,来实现独特的 UI 设计,如不同的主题色、布局、卡…

帮助台技术员协助的自助服务

对于帮助台技术员例行电话带来成本高居不下的企业来说,最终用户自助服务是一个伟大的解决方案,允许用户解决自己的IT问题。然而,一些企业仍未部署自助服务。例如,即使在Active Directory中维护每个员工的最新个人资料信息是一件乏…

1. Python3的安装与环境搭建

1. 开发环境:Win10 Python3.10.5 PyCharm 2. 安装Python3 下载地址:https://www.python.org/ 运行刚下载的python-3.10.5-amd64.exe,并做以下操作: 然后Next,并进行以下操作: 最后点击Install&#…

会话跟踪技术:Cookie、Session和Token

会话跟踪技术背景:1. Cookie (客户端的会话跟踪技术)1.1 原理1.2 基本使用1.2.1 服务器发送Cookie1.2.2 服务器获取Cookie1.3 使用细节1.3.1 存活时间1.3.2 存储中文2. Session(服务端的会话跟踪技术)2.1 原理2.2 基本…

采用高通Qualcomm处理器的手机进EDL 9008模式的办法

由于我们有很多基于 Qualcomm 的设备,其中一些设备可能会古怪地猜测如何进入 EDL 模式,或者如何正确进入。 例如,对于 Alcatel,您必须先按住两个音量键,然后再按住其中一个,对于 CAT B35,您必须…

Python基础(二十六):模块和包简单介绍

文章目录 模块和包简单介绍 一、模块 1、导入模块 2、制作模块

基于Servlet+jsp+mysql开发javaWeb校园图书管理系统

你知道的越多,你不知道的越多 点赞再看,养成习惯 如果您有疑问或者见解,或者没有积分想获取项目,欢迎指教: 企鹅:869192208 文章目录一、开发背景二、 需求分析三、开发环境四、运行效果五、开发流程工程目…

【Android安全】Google Hardware-backed Keystore | SafetyNet | 远程证明Remote Attestation

Google Hardware-backed KeyStore Attestation 原理及流程 SafetyNet Hardware-backed Attestation SafetyNet Hardware-backed Attestation:使用了Hardware-backed Keystore SafetyNet 支持Software Attestation 和 Hardware-backed Attestation,根据…

五、Web应用开发模式

web应用开发模式 web应用的开发主要有两种模式: 前后端不分离前后端分离 前后端不分离 在互联网早期,web应用开发采用前后端不分离的方式。 它是以后端直接渲染模板完成响应的一种开发模式。 以前后端不分离的方式开发的web应用的架构图如下&#x…

每天15分钟JMeter进阶篇(1):JAVA 取样器的基本使用

每天15分钟JMeter进阶篇(1):JAVA 取样器的基本使用前言准备工作创建开发工程POM文件创建根工程创建module开发JAVA取样器构建、部署运行构建JAR包部署和运行写在最后前言 JMETER官方提供了丰富的取样器,可以支持80%的常见测试场景…

传输层协议:UDP协议

简介 用户数据报协议(英语:User Datagram Protocol,缩写:UDP;又称用户数据包协议)是一个简单的面向数据包的通信协议,位于OSI模型的传输层。该协议由David P. Reed在1980年设计且在RFC 768中被…

CrimeFragment的UI fragment进行管理

用户界面将由一个名为CrimeFragment的UI fragment进行管理。CrimeFragment的 实例将通过一个名为CrimeActivity的activity来托管。CrimeActivity视图由FrameLayout组件组成,FrameLayout组件为CrimeFragment要显示 的视图安排了存放位置。 CrimeFragment 的视图由一个…

Thinkphp QVD-2022-46174 多语言rce

文章目录漏洞介绍vulhub漏洞搭建漏洞利用利用一:写入文件利用二:文件包含漏洞分析参考文章漏洞介绍 Thinkphp,v6.0.1~v6.0.13,v5.0.x,v5.1.x 如果 Thinkphp 程序开启了多语言功能,那就可以通过 get、head…

[从零开始]用python制作识图翻译器·三

AlsoEasy-RecognitionTranslator具体实现开发环境准备和验证下载conda创建开发环境文字识别模块在线模块离线模块机器翻译模块在线模块离线模块GUIGUI-定位模块GUI-截图模块具体实现 开发环境准备和验证 前期测试项目文件已上传到我的仓库。 下载conda conda是python的版本管…