Linux网络编程5

news2024/9/24 5:32:57

IO多路复用

1.IO模型

在unix/linu下主要有四种I/O模式: 阻塞I/O: 最常用

大部分程序使用的都是阻塞模式的I/O

阻塞I/O

缺省情况下,套接字建立后所处于的模式就是阻塞I/O模式

读操作:read,recv,recvfrom

写操作:write,send

其他操作:accept,connect

        以read函数为例

        进程调用read函数从套接字上读取数据,当套接字的接收缓冲区中还没有数据可读,函数

read将发送阻塞

        它会一直阻塞下去,等待套接字的接收缓冲区中有数据可读

        经过一段时间后,缓冲区内接收到数据,于是内核便去唤醒该进程,通过read访问这些数据         如果在进程阻塞过程中,对方发生故障,那这个进程将永远阻塞下去。

        UDP不用等待,没有实际的发送缓冲区,所以UDP协议中不存在发送缓冲区满的情况,在

UDP套接字上执行的写操作永远都不会阻塞。

        写阻塞

        在写操作时发送阻塞的情况要比读操作少。主要发生在要写入的缓冲区的大小小于要写入的数 据量的情况下。

        这时,写操作不进行任何拷贝工作,将发送阻塞。

        一但发送缓冲区内有足够多的空间,内核将唤醒进程,将数据从用户缓冲区中拷贝到相应的发 送数据缓冲区。

        UDP不用等待确认,没有实际的发送缓冲区,所以UDP协议中不存在发送缓冲区满的情况, 在UDP套接字上执行的写操作永远都不会阻塞,sendto。

非阻塞I/O:可防止进程阻塞在I/O操作上,需要轮询

当我们将一个套接字设置为非阻塞模式,我们相当于告诉了系统内核"当我请求的I/O操作不能够马上完 成,你想让我的进程进行休眠等待的时候,不要这么做,请马上返回一个错误给我。"

当一个应用程序使用了非阻塞模式的套接字,它需要使用一个循环来不停的测试是否一个文件描述符有 数据可读(polling)。

应用程序不停的polling内核来检查是否I/O操作已经就绪,这将是一个极浪费CPU资源的操作。 这种模式使用中不普遍。

1.fcntl()函数

当你一开始建立一个套接字描述符的时候,系统内核 将其设置为阻塞IO模式。可以使用函数fcntl()

设置一个套接字的标志位为O_NOBLOCK来实现非阻塞。

int fcntl(int fd, int cmd, long arg)   

int flag;  flag = fcntl(sockfd,F_GETFL,0) 

flag |= O_NOBLOCK; 

fcntl(sockfd,F_SETFL,flag); 

2.ioctl()函数

int b_on = 1; 

ioctl(sock_fd, FIONBIO,&b_on); 

I/O多路复用:允许同时对多个I/O进行控制

基本常识:linux中每个进程最多可以打开1024个文件,最多有1024个文件描述符,文件描述符的特 点:

1.非负整数

2.从最小可用的数字来分配

3.每个进程启动时默认打开0、1、2三个文件描述符

多路复用针对不止套接字fd,也针对普通的文件描述符fd。

应用程序中同时处理多路输入输出流,若采用阻塞模式,将得不到预期的目的;

若采用非阻塞模式,对多个输入进行轮询,但又太浪费CPU时间;

若设置多个进程,分别处理一条数据通路,将新产生进程间的同步与通信问题,使程序变得更加复杂;

比较好的方法是使用IO多路复用,其基本思想是: 先构造一张又关描述符的表,然后调用一个函数,当这些文件描述符中的一个或多个已准备好进行

IO时函数才返回。 函数返回时告诉进程那个描述符已就绪,可以进行IO操作

步骤:

1.fd_set

void FD_zero(fd_set* fdset) //对集合清零

void FD_set(int fd, fd_set * fdset) //把fd加入集合

void FD_CLR(int fd,fd_set *fdset) //从集合中清除fd void FD_ISSET(int fd,fd_set *fdset) //判断fd是否在fd_set中

2.select()

int select(int maxfdp, //maxfd+1 fd_set *readfds, //读集合

fd_set *writefds, //写集合

fd_set *errorfds, //异常集合

struct timeval *timeout //超时

);

一般:填写集合,写集合填空,异常集合(带位数据),

超时:

struct  timeval{                    

        long  tv_sec;   //秒                    

        long tv_usec;   //微妙   

}; 

select退出后:集合表示有数据的集合

if(FD_ISSET(fd,set))   {    

 //1.如果监听套接字有数据,新的客户端进行连接,则accept     

//2.若建立连接的套接字有数据,则去读read   

int main(void) 

{    

        struct timeval tout;    

        fd_set rset;   

         int maxfd = ‐1;    

        fd = socket(...);    

        bind(fd,...);    

        listen(fd,...);    

        while(1)    

        {       

                maxfd = fd;           

                FD_ZERO(&rset);      

                FD_SET(&rset); //依次把已经建立好连接fd加入到集合中,记录最大的文件描述符     tout.tv_sec = 5;       

                tout.tv_user = 0;       

                select(maxfd+1,&rset,NULL,NULL,&tout); //阻塞           

                if(FD_ISSET(fd,&rset)) //有1个或者多个文件描述符有数据      

                 {           

                         newfd = accept(fd,...);            

                        //依次判断已建立连接的客户端是否有数据            

                        //xxx             

                 }   

         } 

select()里面的各个文件描述符fd_set集合的参数在select()前后发生了变化

前:表示关心的文件描述符集合

后:有数据的集合(如不是在超时还回情况下)

kernel对集合进行了改变 信号驱动I/O:一种异步通信模型

SIGIO

案例:

服务器端:

客户端:

6.TCPIP协议原理

1.三次、四次挥手 一定要标注客户端和服务器

三次握手的连接必须是由客户端发起(四次握手客户端和服务器都可以发起)

SYN,ACK,FIN等标志符号应该写上。

TCP/IP协议中的三次握手和四次挥手是TCP(传输控制协议)建立连接和断开连接的关键过程。下面分别讲解这两个过程:

三次握手(Three-way Handshake)

三次握手是TCP建立连接的过程,它确保了通信双方都能准备好接收数据。具体过程如下:

  1. 第一次握手
    • 发起方(通常是客户端) 向接收方(通常是服务器)发送一个SYN(同步序列编号)报文段,其中将SYN标志位设置为1,表示这是一个连接请求,并选择一个初始序列号seq=x。此时,客户端进入SYN_SEND状态,等待服务器的确认。
    • SYN报文段:SYN=1,ACK=0,seq=x(x为客户端随机生成的初始序列号)。
  2. 第二次握手
    • 接收方(服务器) 收到SYN报文段后,进行确认,设置自己的SYN标志位为1,ACK标志位为1,表示确认收到客户端的SYN报文段,并将确认号ack设置为x+1(即客户端的初始序列号加1)。同时,服务器也选择一个自己的初始序列号seq=y,并将这些信息(SYN+ACK报文段)发送给客户端。此时,服务器进入SYN_RECV状态。
    • SYN+ACK报文段:SYN=1,ACK=1,seq=y,ack=x+1。
  3. 第三次握手
    • 发起方(客户端) 收到服务器的SYN+ACK报文段后,向服务器发送一个ACK报文段,将ACK标志位设置为1,确认号ack设置为y+1(即服务器的初始序列号加1),表示确认收到服务器的SYN报文段。这个报文段发送完毕后,客户端和服务器都进入ESTABLISHED(已建立连接)状态,此时连接建立成功。
    • ACK报文段:ACK=1,seq=x+1,ack=y+1。

四次挥手(Four-way Handshake)

四次挥手是TCP断开连接的过程,它确保了通信双方都能正常地释放资源。具体过程如下:

  1. 第一次挥手
    • 主动关闭方(可以是客户端或服务器) 发送一个FIN报文段,将FIN标志位设置为1,表示没有数据要发送了,请求关闭连接。此时,主动关闭方进入FIN_WAIT_1状态。
    • FIN报文段:FIN=1,seq=u(u为发送FIN报文段一方的序列号)。
  2. 第二次挥手
    • 被动关闭方 收到FIN报文段后,发送一个ACK报文段,将ACK标志位设置为1,确认号ack设置为u+1,表示确认收到主动关闭方的FIN报文段。此时,被动关闭方进入CLOSE_WAIT状态,而主动关闭方则进入FIN_WAIT_2状态。
    • ACK报文段:ACK=1,seq=v(v为被动关闭方的序列号),ack=u+1。
  3. 第三次挥手
    • 被动关闭方 在数据传送完毕后,也发送一个FIN报文段,请求关闭连接,并设置FIN标志位为1。此时,被动关闭方进入LAST_ACK状态。
    • FIN报文段:FIN=1,ACK=1,seq=w(w为被动关闭方发送FIN报文段时的序列号),ack=u+1。
  4. 第四次挥手
    • 主动关闭方 收到被动关闭方的FIN报文段后,发送一个ACK报文段,将ACK标志位设置为1,确认号ack设置为w+1,表示确认收到被动关闭方的FIN报文段。此时,主动关闭方进入TIME_WAIT状态,等待一段时间后(通常是2倍的MSL,即最长报文段寿命),确保被动关闭方收到自己的ACK报文段后,最终进入CLOSED状态。而被动关闭方在收到ACK报文段后,也进入CLOSED状态。
    • ACK报文段:ACK=1,seq=u+1,ack=w+1。

总结

  • 三次握手 确保了通信双方都能准备好接收数据,是建立TCP连接的关键过程。
  • 四次挥手 确保了通信双方都能正常地释放资源,是断开TCP连接的过程。
  • 这两个过程共同保证了TCP连接的可靠性和资源的有效利用。

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

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

相关文章

【最新】推荐7款智能AI写作论文生成网站工具

在当前的AI技术浪潮中,智能AI写作工具已经成为了学术研究和论文撰写的重要助手。本文将推荐7款高效且功能全面的智能AI写作论文生成网站工具,并重点介绍其中备受好评的千笔-AIPassPaPer。 1. 千笔-AIPassPaPer 千笔-AIPassPaPer是一款集多种功能于一体…

最近在写的支付模块

最近再写支付模块就到处借鉴 旨在回顾一下。 1.确认订单功能 使用场景是:用户在选择好购物车后,或者是直接选择商品后(选择商品封装为购物车) 这样做是根据尚硅谷来学习的 目前需要这些属性,原因是在确认订单页面后…

如何采集淘宝商品评论?

采集商品评论对于企业和消费者都至关重要。它不仅帮助企业了解产品优势与不足,指导产品改进和市场策略调整,还能通过积极回应顾客反馈增强品牌忠诚度。对消费者而言,真实客观的评价是决策的重要参考,有助于避开潜在问题&#xff0…

Apache Tomcat 7下载、安装、环境变量配置 详细教程

Apache Tomcat 7下载、安装、环境变量配置 详细教程 Apache Tomcat 7下载Apache Tomcat 7 安装Apache Tomcat 7 环境变量配置启动 Apache Tomcat 7测试Tomcat7是否启动成功 Apache Tomcat 7下载 1、下载地址,找到Archives 链接: 官网下载地址 2、找到Tomcat 7&…

Linux查看系统线程数

Linux查看系统线程数 查看线程数查看进程内的线程统计线程数 查看线程数 想要查看Linux操作系统允许的最大线程数,可以通过命令 ulimit -a返回配置项的详细说明: # core文件的最大值为100blocks core file size (blocks, -c) 0# 进程的数…

[区间概率预测]CNN-BiLSTM-Attention-ABKDE多变量时序预测 基于改进自适应核密度估计实现区间预测

[区间概率预测]CNN-BiLSTM-Attention-ABKDE多变量时序预测 基于改进自适应核密度估计实现区间预测 【原创区间概率预测】CNN-BiLSTM-Attention-ABKDE多变量时序预测 基于卷积神经网络-双向长短期记忆神经网络-注意力机制结合自适应带宽核函数密度估计的多变量时序预测【点预测…

【51单片机仿真】基于51单片机设计的温度检测与高低温报警系统仿真源码设计文档演示视频——文末资料下载

基于51单片机设计的温度检测与高低温报警系统仿真设计 演示视频 基于51单片机设计的温度检测与高低温报警系统仿真 系统功能简介 1、实时温度测量,可调整温度值 2、显示测量的温度值,按键切换可查看高温和低温报警值 3、可通过按键输入报警最高值以及最…

8/8总结

1.三分 | 函数 虽然提示很明显了&#xff0c;但是还是没掌握套路&#xff0c;看了题解才会的&#xff0c;估计也有四分&#xff0c;就是三次方的形式。 例子&#xff1a; 2 1 2 0 0 2 2 0 0 2 -4 2AC: #include<bits/stdc.h> using namespace std; const int maxn1001…

动态规划(一)

目录 &#xff08;一&#xff09;递归到动规的一般转化方法 &#xff08;二&#xff09;动规解题的一般思路 1. 将原问题分解为子问题 2. 确定状态 3. 确定一些初始状态&#xff08;边界状态&#xff09;的值 4. 确定状态转移方程 &#xff08;三&#xff09;能用动规解…

【Android Studio】Webview 内核升级得三种方法

【Android Studio】Webview 内核升级得三种方法 前言X5 腾讯组件crosswalk开源项目webview升级加载的内核&#xff08;完美解决&#xff09;总结 前言 在APP 中进行网页加载&#xff0c;一般采用原生自带的Webview 组件&#xff0c;但在需要加载高版本网页的时候&#xff0c;有…

工业三防平板助力MES系统打造工厂移动式生产管理

随着工业4.0时代的到来&#xff0c;智能制造、数字化车间等概念层出不穷&#xff0c;生产过程的可视化管理也成为了企业提升效率、优化生产的关键。而工业三防平板&#xff0c;凭借其坚固耐用、功能强大、便携易用等特性&#xff0c;成为了实现生产过程可视化管理的重要利器&am…

SQL注入实例(sqli-labs/less-21)

与第20关无异&#xff0c;只多了一步base64加密 0、初始页面 1、确定闭合字符 2、爆库名 3、爆表名 4、爆列名 5、查询最终目标

POS刷卡开发源码之语音播报-CyberWinApp-SAAS 本地化及未来之窗行业应用跨平台架构

一、终端语音提醒的好处 1. 增强信息传递的有效性&#xff1a;在人们忙碌或者注意力分散时&#xff0c;语音提醒能够直接穿透噪音和干扰&#xff0c;确保重要信息被准确接收。 2. 提高操作的便捷性&#xff1a;用户无需停下手中的工作去查看屏幕或阅读文字&#xff0c;直接通过…

算法——动态规划:0/1 背包问题

文章目录 一、问题描述二、解决方案1. DP 状态的设计2. 状态转移方程3. 算法复杂度4. 举例5. 实现6. 滚动数组6.1 两行实现6.2 单行实现6.3 优缺点 三、总结 一、问题描述 问题的抽象&#xff1a;给定 n n n 种物品和一个背包&#xff0c;第 i i i 个物品的体积为 c i c_i …

NET8中WebAPI使用JWT入门教程

目录 1、JWT2、具体实现3、代码下载 1、JWT 现在在各类API的开发中&#xff0c;token已经是必备了。例如&#xff1a;微信公众号开发中&#xff0c;第一个方法就是获取token。JWT具体的定义及组成部分大家可以到网上找找&#xff0c;这儿给一个简单的描述&#xff1a;JWT 令牌…

yaml语法+yaml配置文件

yaml语法 k:(空格)v > 表示一对键值对空格必须有 yaml拥有严格的空格缩进格式控制&#xff0c;以空格的缩进来控制层级关系&#xff1b;只要是左对齐的一列数据&#xff0c;都是同一个层级的 spring:thymeleaf:cache: true# 检查模板是否存在&#xff0c;然后再呈现check…

通义灵码-阿里云推出的AI智能编码助手

通义灵码体验地址 标题通义灵码是什么&#xff1f; 通义灵码是由阿里巴巴推出的基于通义大模型的智能编码辅助工具&#xff0c;提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码注释生成、代码解释、研发智能问答、异常报错排查等能力&#xff0c;并针对阿里云…

Bug 解决 | 前端无法正确请求后端接口并得到响应?

目录 1、配置问题 2、代码问题 3、网络问题 前端请求后端接口发现得到的响应不对&#xff0c;或者通过 f12 明明看到了后端的响应&#xff0c;但是前端页面无法正常的展示出来。 这种情况该怎么排查呢&#xff1f;这篇我们就来好好的理一理&#xff01; 1、配置问题 1&am…

浅谈取样器插件之jp@gc - UDP Request

浅谈取样器插件之jpgc - UDP Request JPgc - UDP Request允许用户在性能测试中发送UDP&#xff08;User Datagram Protocol&#xff09;数据包。这对于测试那些依赖UDP协议进行通信的应用程序和服务特别有用&#xff0c;比如某些物联网&#xff08;IoT&#xff09;设备、在线游…

我在高职教STM32——I2C通信入门(2)

大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正是如此,才有了借助CSDN平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思设计的教学课件分…