网络编程 IO多路复用 [select版] (TCP网络聊天室)
//head.h 头文件
//TcpGrpSer.c 服务器端
//TcpGrpUsr.c 客户端
select函数
功能:阻塞函数,让内核去监测集合中的文件描述符是否准备就绪,若准备就绪则解除阻塞。
原型:
#include <sys/select.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout); 参数:int nfds:所有集合中最大的文件描述符+1; fd_set *readfds, fd_set *writefds,fd_set *exceptfds:读集合,写集合,其他集合。用不上的集合填NULL;struct timeval *timeout:设置超时时间; 1) 填NULL,不设置超时时间,会一直阻塞直到文件描述符准备就绪,解除阻塞;2) 设置超时时间;struct timeval {long tv_sec; /* seconds */ 秒long tv_usec; /* microseconds */ 微秒}; 返回值:>0, 成功,返回成功触发事件的文件描述符个数;=0, 超时了=-1,函数运行失败,更新errno; 操作集合的函数: void FD_CLR(int fd, fd_set *set); 将指定的fd从集合中删除int FD_ISSET(int fd, fd_set *set); 判断fd是否在集合中,若存在返回真,否则返回假void FD_SET(int fd, fd_set *set); 将fd添加到集合中void FD_ZERO(fd_set *set); 清空
head.h
#ifndef __HEAD_H__
#define __HEAD_H__#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<strings.h>
#include<unistd.h>
#include<math.h>
#include<errno.h>
#include<fcntl.h>
#include<signal.h>#include<sys/stat.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/shm.h>
#include<sys/time.h>
#include<sys/sem.h>#include<pthread.h>
#include<semaphore.h>#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/select.h>
#include<poll.h>#define NUM 10
#define ERR_MSG(msg) do{\printf("line: %d\n",__LINE__);\perror(msg);\
}while(0)
#define PORT 6666 //端口号的网络字节序 1024~49151
#define IP "192.168.250.100" //ifconfig查看本机IP (ipv4)#endif
TcpGrpSer.c
#include "head.h"int main(int argc, const char *argv[])
{//创建流式套接字int sfd = socket(AF_INET,SOCK_STREAM,0);if(sfd<0){ERR_MSG("socket");return -1;}//填充服务器自身的地址信息结构体//真实的地址信息结构体根据地址族制定AF_INET ; man 7 ipstruct sockaddr_in sin; sin.sin_family = AF_INET; //必须填充AF_INETsin.sin_port = htons(PORT); //端口号的网络字节序 1024~49151sin.sin_addr.s_addr = inet_addr(IP); //ifconfig查看本机IPint reuse = 1;if(setsockopt(sfd, SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) < 0) //允许端口快速被重复使用{ERR_MSG("setsockopt");return -1;}//绑定连接if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0){ERR_MSG("bind");return -1;}printf("bind success\n");//设置监听if(listen(sfd,128) < 0){ERR_MSG("listen");return -1;}//创建读集合fd_set readfds,tempfds;//清空集合FD_ZERO(&readfds);FD_ZERO(&tempfds);//将集合监测的文件描述符放入集合FD_SET(0,&readfds);FD_SET(sfd,&readfds);//用顺序表存储文件描述符的端口信息//监测文件描述符是否准备就绪int maxfd = sfd;int s_res = 0;struct sockaddr_in cin;socklen_t len = sizeof(cin);struct sockaddr_in savcin[1024];int newfd = -1;char buf[128]="";ssize_t res = 0;while(1){tempfds = readfds;//备份readfdss_res = select(maxfd+1,&tempfds,NULL,NULL,NULL);if(s_res<0){ERR_MSG("select");return -1;}else if(0 == s_res){printf("超时...\n");break;}//与客户端通信for(int i=0;i<=maxfd;i++){if(!FD_ISSET(i,&tempfds))continue;if(0 == i){printf("触发键盘输入事件\n");int sndfd=-1;res=scanf("%d %s",&sndfd,buf);while(getchar() !=10);if(res!=2){printf("请输入正确数据格式:[fd(4~1023)] string\n"); continue;}//判断文件是否合法if(sndfd<sfd||sndfd>1023||!FD_ISSET(sndfd,&readfds)){printf("sndfd = %d 是非法文件描述符\n",sndfd);continue;}if(send(sndfd,buf,sizeof(buf),0)<0){ERR_MSG("send");}bzero(buf,sizeof(buf));}else if(i == sfd){printf("触发客户端连建事件\n");newfd = accept(sfd,(struct sockaddr *)&cin,&len);if(newfd < 0){perror("accept");return -1;}savcin[newfd]=cin;printf("[%s:%d] 客户端连接成功 newfd = %d __%d__ \n",\inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd,__LINE__);//将新生成的newfd添加到readfdsFD_SET(newfd,&readfds);//更新maxfdmaxfd = maxfd > newfd? maxfd:newfd;}else{printf("触发客户端连建事件__%d__\n",__LINE__);bzero(buf,sizeof(buf));//接收数据res = recv(i,buf,sizeof(buf),0);if(res < 0){ERR_MSG("recv");return -1;}else if(0 == res){printf("{%s:%d} sfd = %d,__%d__ 已下线,结束对话\n",\inet_ntoa(savcin[i].sin_addr),ntohs(savcin[i].sin_port),i,__LINE__); close(i);//关闭文件描述符FD_CLR(i,&readfds);/* //更新maxfdint j=maxfd;for(;j<=0;j--){if(FD_ISSET(j,&readfds)) break;}maxfd = j;*///更新maxfdwhile(!FD_ISSET(maxfd,&readfds)&&maxfd-->=0);continue;}printf("{%s:%d} sfd = %d : %s,__%d__\n",\inet_ntoa(savcin[i].sin_addr),ntohs(savcin[i].sin_port),i,buf,__LINE__); //发送数据strcat(buf,"*_*");if(send(i,buf,sizeof(buf),0)<0){ERR_MSG("send");return -1;}printf("发送成功\n");}}}if(close(sfd)<0){ERR_MSG("close");return -1;}return 0;
}
TcpGrpUsr.c
#include "head.h"int main(int argc, const char *argv[])
{//创建流式套接字int sfd = socket(AF_INET,SOCK_STREAM,0);if(sfd<0){ERR_MSG("socket");return -1;}int reuse = 1;if(setsockopt(sfd, SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) < 0) //允许端口快速被重复使用{ERR_MSG("setsockopt");return -1;}//填充服务器自身的地址信息结构体//真实的地址信息结构体根据地址族制定AF_INET ;struct sockaddr_in sin; sin.sin_family = AF_INET; //必须填充AF_INETsin.sin_port = htons(PORT); //端口号的网络字节序 1024~49151sin.sin_addr.s_addr = inet_addr(IP); //ifconfig查看本机IPif(connect(sfd,(struct sockaddr *)&sin,sizeof(sin))<0){perror("connect");return -1;}printf("连接成功\n");//创建集合struct pollfd fds[2];fds[0].fd = 0;fds[0].events = POLLIN;fds[1].fd = sfd;fds[1].events = POLLIN;char buf[128]="";int res=0;while(1){//阻塞方式监测集合res = poll(fds,2,-1);if(res < 0){ERR_MSG("poll");return -1;}else if(0 == res){printf("time out...\n"); //超时break;}//判断0文件描述符是否有POLLIN事件if((fds[0].revents & POLLIN)){fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] = 0;if(send(sfd,buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}printf("发送成功\n");}//判断sfd文件描述符是否有POLLIN事件if(fds[1].revents & POLLIN){//接收数据bzero(buf,sizeof(buf));res = recv(sfd,buf,sizeof(buf),0);if(res<0){ERR_MSG("recv");return -1;}else if(res == 0){printf("[%s:%d] 服务器下线__%d__ \n",\inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),__LINE__);break;}printf("[%s:%d] cfd = %d : %s__%d__ \n",\inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),sfd,buf,__LINE__);} }if(close(sfd)<0){ERR_MSG("close");return -1;}return 0;
}
相关文章:

网络编程 IO多路复用 [select版] (TCP网络聊天室)
//head.h 头文件 //TcpGrpSer.c 服务器端 //TcpGrpUsr.c 客户端 select函数 功能:阻塞函数,让内核去监测集合中的文件描述符是否准备就绪,若准备就绪则解除阻塞。 原型: #include <sys/select.…...

数学建模学习(7):单目标和多目标规划
优化问题描述 优化 优化算法是指在满足一定条件下,在众多方案中或者参数中最优方案,或者参数值,以使得某个或者多个功能指标达到最优,或使得系统的某些性能指标达到最大值或者最小值 线性规划 线性规划是指目标函数和约束都是线性的情况 [x,fval]linprog(f,A,b,Aeq,Beq,LB,U…...

Element UI如何自定义样式
简介 Element UI是一套非常完善的前端组件库,但是如何个性化定制其中的组件样式呢?今天我们就来聊一聊这个 举例 就拿最常见的按钮el-button来举例,一般来说默认是蓝底白字。效果图如下 可是我们想个性化定制,让他成为粉底红字应…...
protobuf入门实践2
如何在proto中定义一个rpc服务? syntax "proto3"; //声明protobuf的版本package fixbug; //声明了代码所在的包 (对于C来说就是namespace)//下面的选项,表示生成service服务类和rpc方法描述, 默认是不生成的 option cc_generi…...
adb shell使用总结
文章目录 日志记录系统概览adb 使用方式 adb命令日志过滤按照告警等级进行过滤按照tag进行过滤根据告警等级和tag进行联合过滤屏蔽系统和其他App干扰,仅仅关注App自身日志 查看“当前页面”Activity文件传输截屏和录屏安装、卸载App启动activity其他 日志记录系统概…...
UG NX二次开发(C++)-Tag的含义、Tag类型与其他的转换
文章目录 1、前言2、Tag号的含义3、tag_t转换为int3、TaggedObject与Tag转换3.1 TaggedObject定义3.2 TaggedObject获取Tag3.3 根据Tag获取TaggedObject4.Tag与double类型的转换1、前言 在UG NX中,每个对象对应一个tag号,C++中,其类型是tag_t,一般是5位或者6位的int数字,…...

Informer 论文学习笔记
论文:《Informer: Beyond Efficient Transformer for Long Sequence Time-Series Forecasting》 代码:https://github.com/zhouhaoyi/Informer2020 地址:https://arxiv.org/abs/2012.07436v3 特点: 实现时间与空间复杂度为 O ( …...

c语言位段知识详解
本篇文章带来位段相关知识详细讲解! 如果您觉得文章不错,期待你的一键三连哦,你的鼓励是我创作的动力之源,让我们一起加油,一起奔跑,让我们顶峰相见!!! 目录 一.什么是…...

FFmpeg aresample_swr_opts的解析
ffmpeg option的解析 aresample_swr_opts是AVFilterGraph中的option。 static const AVOption filtergraph_options[] {{ "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,{ .i64 AVFILTER_THREAD_SLICE }, 0, INT_MA…...

CAN学习笔记3:STM32 CAN控制器介绍
STM32 CAN控制器 1 概述 STM32 CAN控制器(bxCAN),支持CAN 2.0A 和 CAN 2.0B Active版本协议。CAN 2.0A 只能处理标准数据帧且扩展帧的内容会识别错误,而CAN 2.0B Active 可以处理标准数据帧和扩展数据帧。 2 bxCAN 特性 波特率…...

软工导论知识框架(二)结构化的需求分析
本章节涉及很多重要图表的制作,如ER图、数据流图、状态转换图、数据字典的书写等,对初学者来说比较生僻,本贴只介绍基础的轮廓,后面会有单独的帖子详解各图表如何绘制。 一.结构化的软件开发方法:结构化的分析、设计、…...
[SQL挖掘机] - 算术函数 - abs
介绍: 当谈到 SQL 中的 abs 函数时,它是一个用于计算数值的绝对值的函数。“abs” 代表 “absolute”(绝对),因此 abs 函数的作用是返回一个给定数值的非负值(即该数值的绝对值)。 abs 函数接受一个参数&a…...
vue拼接html点击事件不生效
vue使用ts,拼接html,点击事件不生效或者报 is not defined 点击事件要用onclick 不是click let data{name:测,id:123} let conHtml <div> "名称:" data.name "<br>" <p class"cursor blue&quo…...
【Spring】Spring之依赖注入源码解析
1 Spring注入方式 1.1 手动注入 xml中定义Bean,程序员手动给某个属性赋值。 set方式注入 <bean name"userService" class"com.firechou.service.UserService"><property name"orderService" ref"orderService"…...

【微软知识】微软相关技术知识分享
微软技术领域 一、微软操作系统: 微软的操作系统主要是 Windows 系列,包括 Windows 10、Windows Server 等。了解 Windows 操作系统的基本使用、配置和故障排除是非常重要的。微软操作系统(Microsoft System)是美国微软开发的Wi…...
12.python设计模式【观察者模式】
内容:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变的时候,所有依赖于它的对象得到通知并被自动更新。观者者模式又称为“发布-订阅”模式。比如天气预报,气象局分发气象数据。 角色: 抽象主题…...

重生之我要学C++第五天
这篇文章主要内容是构造函数的初始化列表以及运算符重载在顺序表中的简单应用,运算符重载实现自定义类型的流插入流提取。希望对大家有所帮助,点赞收藏评论,支持一下吧! 目录 构造函数进阶理解 1.内置类型成员在参数列表中的定义 …...

复习之linux高级存储管理
一、lvm----逻辑卷管理 1.lvm定义 LVM是 Logical Volume Manager(逻辑卷管理)的简写,它是Linux环境下对磁盘分区进行管理的一种机制。 逻辑卷管理器(LogicalVolumeManager)本质上是一个虚拟设备驱动,是在内核中块设备和物理设备…...

HuggingGPT Solving AI Tasks with ChatGPT and its Friends in Hugging Face
总述 HuggingGPT 让LLM发挥向路由器一样的作用,让LLM来选择调用那个专业的模型来执行任务。HuggingGPT搭建LLM和专业AI模型的桥梁。Language is a generic interface for LLMs to connect AI models 四个阶段 Task Planning: 将复杂的任务分解。但是这里…...
java工程重写jar包中class类覆盖问题
结论:直接在程序中复写jar中的类即可 原因:一般我java工程是运行在tomcat容器中,tomcat容易在加载我们工程类和jar包是的优先级为: 我们工程的class 先于 我们工程lib下的jar 重复的类只加载一次,加载我们复写后的类后…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...