Linux网络编程 day4

inet_pton:IP 字符串 → 网络字节序地址
ntohl:网络字节序 → 主机字节序

TCP状态转换图(重点) 

可以通过下面这行代码查看目前网络状态

netstat -apn | grep client

 

1、主动发起请求端  close-->SYN-->SYN_SENT-->接收ACK、SYN-->SYN_SENT-->发送ACK-->ESTABLISHED(数据通信状态).

2、主动关闭请求端ESTABLISHED-->发送FIN-->FIN_WAIT_1-->接收ACK-->FIN_WAIT_2(半关闭)-->接收对端FIN-->FIN_WAIT_2-->发送ACK-->TIME_WAIT-->等待2MSL时长-->CLOSE.

只有主动关闭连接方会经历TIME_WAIT状态。

3、被动接收连接请求端 close-->LISTEN-->接收SYN-->LISTEN-->发送ACK、SYN-->SYN_RCVD-->接收ACK-->ESTABLISHED.

4、被动关闭连接请求端ESTABLISHED-->接收SYN-->ESTABLISHED-->发送ACK-->CLOSE_WAIT-->发送FIN-->LAST_ACK-->接收ACK-->CLOSE. 

当被动关闭连接请求端处于CLOSE_WAIT的时候,主动关闭连接请求端处于半关闭状态。

重点记忆:ESTABLISHED、FIN_WAIT_2 <---->CLOSE_WAIT、TIME_WAIT(2MSL).

2MSL时长

一定出现在主动发送请求端。

保证最后一个ACK能成功被对端接收。(等待期间,对端没收到我发的ACK,对端会再次发送FIN请求)。

端口复用(让端口重复利用,固定操作)

在server代码的socket和bind之间插入下面代码

int opt = 1; // 取值一般只有两个 0/1
setsockopt(listenfd , SOL_SOCKET , SO_REUSEADDR , (void*)&opt , sizeof(opt));SO_REUSEADDR:允许重用本地地址
SO_RESUEPORT:允许重用本地端口成功返回0,失败-1

半关闭

通信双方中只有一端关闭通信 ---FIN_WAIT_2.

close(cfd);

close(cfd);
shutdown(int fd , int how);
how:   SHUT_RD;   关读端 SHUT_WR;   关写端SHUT_RDWR; 关读写端

这个函数不是很重要,结论:shutdown在关闭多个文件描述符应用的文件时,采用全关闭的方法,close只关闭一个(主要在dup2的时候用到的区别)。

select多路IO转接

借助内核,select来监听客户端连接、数据通信事件。

之前做的CS模型中都是服务器端自己做连接以及read/write等操作,这种方法相当于是有了一个秘书select,服务器端创建了lfd之后交给select,select监听是否有要建立连接的客户端,如果有,反馈给服务器端,让服务器端调用accept函数,创建cfd,之后再交给select,如果select监听到客户端有传数据的需求再反馈给服务器端。

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);nfds:所有监听的最大的文件描述符+1
fd_set *readfds, fd_set *writefds, fd_set *exceptfds:传入传出参数
fd_set *readfds:读文件描述符监听集合
fd_set *writefds:写文件描述符监听集合
fd_set *exceptfds:异常文件描述符监听集合
通常写和异常不使用,一般用NULL
可以参考位图timeout > 0 设置监听超时时长
timeout = 0 非阻塞监听,轮询
timeout = NULL 阻塞监听返回值 > 0 , 所有监听集合(3)中 , 满足对应事件总数
返回值 = 0 ,  所有监听集合(3)中 , 没有满足对应事件总数
返回值 = -1 , errno

 FD_ZERO

清空一个文件描述符集合。

void FD_ZERO(fd_set *set);eg. fd_set rset;
FD_ZERO(&rset);

 FD_SET

将待监听的文件描述符,添加到监听集合中。

void FD_SET(int fd, fd_set *set);
eg.
fd_set rset;
FD_ZERO(&rset);
FD_SET(3 , &rset);

FD_CLR

将一个文件描述符从监听集合中移除。

void FD_CLR(int fd, fd_set *set);

FD_ISSET

判断一个文件描述符是否在监听集合中。

int  FD_ISSET(int fd, fd_set *set);
返回值:在返回1 不在返回0

多路复用IO转接代码思路

lfd = socket();                  //创建套接字
bind();                          //绑定地址结构
listen();                        //设置监听上限
fd_set rset , allset;            //创建读监听集合
FD_ZERO(&rset);                  
FD_ZERO(&allset);                //将读监听集合清零
FD_SET(lfd , &allset);           //将lfd添加至读监听集合中
while(1){rset = allset;ret = select(lfd + 1 , &rset , NULL , NULL , NULL); //监听文件描述符集合对应的事件if(ret > 0){if(FD_ISSET(lfd , &rset))  //1 在 , 0不在{    cfd = accept();FD_SET(cfd , &allset);}for(i = lfd + 1 ; i <= 最大文件描述符; i++){FD_ISSET(i , &rset);read();toupper();write();}}
}
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<ctype.h>
#define SER_PORT 9003void sys_err(char* s)
{perror(s);exit(1);
}int main(int argc , char *argv[])
{int lfd , cfd ,maxfd , i , n , k;char buf[BUFSIZ];struct sockaddr_in serv_addr , clit_addr;socklen_t clit_addr_len;bzero(&serv_addr , sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(SER_PORT);serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);lfd = socket(AF_INET , SOCK_STREAM , 0);if(lfd == -1)sys_err("socket error");int opt = 1;setsockopt(lfd , SOL_SOCKET , SO_REUSEADDR , (void*)&opt , sizeof(opt));int ret = bind(lfd , (struct sockaddr*)&serv_addr , sizeof(serv_addr));if(ret == -1)sys_err("bind error");listen(lfd , 128);fd_set rset , allset; //定义读集合和备份集合FD_ZERO(&rset);FD_ZERO(&allset);FD_SET(lfd , &allset); //添加到读集合中maxfd = lfd; //最大文件描述符while(1){rset = allset; //备份ret = select(maxfd + 1 , &rset , NULL , NULL , NULL); //使用select监听clit_addr_len = sizeof(clit_addr);if(ret > 0){if(FD_ISSET(lfd , &rset)){cfd = accept(lfd , (struct sockaddr*)&clit_addr , &clit_addr_len); //建立连接,不会阻塞。FD_SET(cfd , &allset); //将新产生的cfd添加到监听读集合中,监听数据读事件if(maxfd < cfd)maxfd = cfd;if(ret == 1) //说明select只返回一个并且是lfd,后续无需执行。continue;}for(i = lfd + 1 ; i <= maxfd ; i++){   //处理满足读事件的fdif(FD_ISSET(i , &rset)){            //找到满足读事件的fdn = read(i , buf , sizeof(buf));if(n == 0){    //检测到客户端关闭close(i);  FD_CLR(i , &allset); // 移除}else if(n < 0){sys_err("read error");}else{for(k = 0 ; k < n ; k++){buf[k] = toupper(buf[k]);}write(STDOUT_FILENO , buf , n);write(i , buf , n);}}}}else if(ret < 0){sys_err("select error");}}close(cfd);return 0 ;
}

但是上述代码有个问题,就是当rset为[3,6,1023],相当于要循环判断1023次,运行效率低。可以自定义一个数组,将要监听的文件描述符放到数组中。然后根据下标索引取出需要的文件描述符。

select的优缺点

缺点:

1、监听上限受文件描述符限制,最大1024。

2、检测满足条件的fd,自己添加业务逻辑提高小。提高了编码难度。

优点:

1、跨平台。win、Linux、macos、unix、mips。

 

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

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

相关文章

基于springboot+vue的个人财务管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat12开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;Maven3.3.9 系统展示 用户信息管理 账…

ffmpeg 元数据-avformatcontext字段 AVDictionary *metadata;

ffmpeg 元数据 1. 解释什么是ffmpeg元数据 ffmpeg元数据是指与音视频文件相关的附加信息&#xff0c;这些信息不直接影响音视频内容的播放&#xff0c;但提供了关于文件内容、创作者、版权、播放参数等的有用信息。元数据在音视频文件的处理、管理和共享中起着重要作用。 2.…

55.[前端开发-前端工程化]Day02-包管理工具npm等

包管理工具详解 npm、yarn、cnpm、npx、pnpm 1 npm包管理工具 代码共享方案 包管理工具npm 2 package配置文件 npm的配置文件 方式二 常见的配置文件 常见的属性 常见的属性 常见的属性 依赖的版本管理 常见属性 npm install 命令 项目安装 3 npm install原理 npm instal…

Spring MVC @RequestBody 注解怎么用?接收什么格式的数据?

RequestBody 注解的作用 RequestBody 将方法上的参数绑定到 HTTP 请求的 Body&#xff08;请求体&#xff09;的内容上。 当客户端发送一个包含数据的请求体&#xff08;通常在 POST, PUT, PATCH 请求中&#xff09;时&#xff0c;RequestBody 告诉 Spring MVC 读取这个请求体…

海外平台短剧批量混剪自动剪辑智能去重与多语言适配方案解析

一、引言&#xff1a;全球化内容分发的技术挑战 在短剧出海的浪潮中&#xff0c;如何通过标准化技术流程实现「高效生产 合规分发」成为行业关键课题。本文结合 TikTok、YouTube 等平台的运营经验&#xff0c;解析基于智能去重算法、多语言字幕生成、动态元素叠加的全流程解决…

stm32 hal库 SPI使用(二)硬件SPI的HAL库函数调用

使用硬件SPI1&#xff0c;开启DMA&#xff0c;软件NSS。 1.使用硬件spi后&#xff0c;spi.c文件里会自动生成SPI_HandleTypeDef hspi1句柄&#xff0c;并且在main.c中自动使用MX_SPI1_Init&#xff08;&#xff09;函数对hsp1句柄赋值和SPI初始化 void MX_SPI1_Init(void) {h…

ES类的索引轮换

通过以下请求方法创建一个名为 “tiered-storage-policy” 的 ISM policy&#xff1a; PUT _plugins/_ism/policies/tiered-storage-policy {"policy": {"description": "Changes replica count and deletes.","schema_version": 1,…

51LA使用方法与悟空统计,网站数据分析的双重选择

在网站运营与数据分析领域&#xff0c;51LA作为国内较早的流量统计工具&#xff0c;曾为许多用户提供基础的访问数据监测服务。然而&#xff0c;随着技术的发展和用户需求的升级&#xff0c;越来越多的企业开始寻求功能更全面、体验更优的统计工具。小编今天将给大家介绍一款更…

go语言实现用户管理系统

goweb实现用户管理系统 用户后台管理系统功能描述 登录功能 支持用户通过邮箱密码和密码进行登录。对输入的邮箱和密码进行验证&#xff0c;确保用户信息的正确性。登录成功后&#xff0c;更新用户的今日登录统计信息&#xff0c;并将用户信息存入会话&#xff08;cookie&am…

Elasticsearch:RAG 和 grounding 的价值

作者&#xff1a;来自 Elastic Toms Mura 了解 RAG、grounding&#xff0c;以及如何通过将 LLM 连接到你的文档来减少幻觉。 更多阅读&#xff1a;Elasticsearch&#xff1a;在 Elastic 中玩转 DeepSeek R1 来实现 RAG 应用 想获得 Elastic 认证吗&#xff1f;查看下一期 Elast…

【黑马JavaWeb+AI知识梳理】后端Web基础01 - Maven

Maven Maven核心 Maven概述 定义&#xff1a; Maven是一款用于管理和构建Java项目的工具&#xff0c;是apache旗下的一个开源项目&#xff0c;基于项目对象模型&#xff08;POM&#xff0c;project object model&#xff09;的概念&#xff0c;通过一小段描述信息来管理项目的…

C语言易混淆知识点详解

C语言中容易混淆的知识点详解 C语言作为一门基础且强大的编程语言&#xff0c;有许多容易混淆的概念和特性。以下是C语言中一些常见易混淆知识点的详细解析&#xff1a; 1. 指针与数组 相似点&#xff1a; c 复制 下载 int arr[10]; int *ptr arr; 都可以使用[]运算符访…

MCP原理详解及实战案例(动嘴出UI稿、3D建模)

文章目录 MCP 原理介绍架构核心组件协议层传输层连接生命周期MCP与function calling: 互补关系 MCP python SDKMCP的优点 怎么用MCP&#xff1a;天气服务参考应用项目&#xff1a; REF 24年11月份&#xff0c;claude推出了模型上下文协议( MCP),作为一种潜在的解决方案&#xf…

2025年深圳杯数学建模(东三省)B题【颜色转换】原论文讲解(含完整python代码)

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了2025年深圳杯数学建模&#xff08;东三省&#xff09;B题【颜色转换】完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成…

cpp学习笔记1--class

2年前学过cpp&#xff0c;但是一直没有用到&#xff0c;现在要读研了&#xff0c;终于要用到了&#xff0c;重新拿出来看一看&#xff0c;觉得很多东西都能在c和python上看到影子。 #include "iostream" class Person { private:std::string name;int age;public://…

基于YOLOv的目标检测训练数据构建方法研究—图像采集、标注、划分与增强一体化流程设计

在目标检测任务中,高质量的训练数据是模型性能提升的关键。本文围绕 YOLOv 系列模型,系统性地研究了目标检测训练数据的构建方法,提出了一套从图像采集、标注、数据集划分到数据增强的一体化流程设计 。通过多源图像采集策略确保样本多样性,结合 LabelImg 工具完成 VOC 格式…

SQL数据库操作大全:从基础到高级查询技巧

大家好&#xff0c;欢迎来到程序视点&#xff01;我是你们的老朋友.小二&#xff01; SQL数据库操作核心语法精要 数据库基础操作 创建/删除数据库&#xff1a;CREATE DATABASE / DROP DATABASE 备份SQL Server&#xff1a;使用sp_addumpdevice和BACKUP DATABASE命令 数据库…

[2025]MySQL的事务机制是什么样的?redolog,undolog、binog三种日志的区别?二阶段提交是什么?ACID怎么保证的?主从复制的过程?

MySQL事务机制与日志系统详解 一、MySQL事务机制 1. 事务特性&#xff08;ACID&#xff09; 特性实现机制原子性(Atomicity)undo log回滚,(事务作为一个整体被执行&#xff0c;包含在其中的对数据库的操作要么全部被执行&#xff0c;要么都不执行)。一致性(Consistency)约束…

LLama-v2 权重下载

地址&#xff1a;llama模型 官方github仓库&#xff1a;llama仓库 注意点 网络代理位置&#xff1a;美国下面的国家选择 United States 克隆仓库后 运行bash download.sh输入邮箱收到的URL选择要下载的权重等待下载完成即可 有问题留言&#xff01;&#xff01;&#xff01…

zephyr OS架构下构建Nordic MCU boot

目录 概述 1. 软硬件环境 1.1 软件开发环境 1.2 硬件环境 2 MCU boot 2.1 核心功能 2.2 关键术语 2.3 重要字段介绍 3 VS-Code下创建MCU-BOOT项目 3.1 软件框架结构 3.2 创建测试项目 3.3 编译项目 3.3 固件在Flash中的分布 4 验证 4.1 烧写固件 ​ 4.2 代码…