2024.8.21
作业:
运行1个服务器和2个客户端 实现效果: 服务器和2个客户端互相聊天,服务器和客户端都需要使用select模型去实现 服务器要监视2个客户端是否连接,2个客户端是否发来消息以及服务器自己的标准输入流 客户端要监视服务器是否发来消息以及客户端自己的标准输入流 在不开线程的情况下,实现互相聊天
代码实现
服务器
#include<myhead.h>
#define SER_PORT 6666 //服务器端口号
#define SER_IP "10.80.15.182" //服务器ip地址
void insert_client(int*client_addr,int *len,int client)
{client_addr[*len] = client;(*len)++;
}int find_client(int*client_addr,int len,int client)
{for(int i=0;i<len;i++){if(client_addr[i] == client){return i;}}return -1;
}void remove_client(int*client_addr,int *len,int client)
{int tar = find_client(client_addr,*len,client);if(tar == -1){return;}int i = -1;for(i=tar;i<*len;i++){client_addr[i] = client_addr[i+1];}(*len)--;
}int main(int argc, const char *argv[])
{int flag = fcntl(0,F_GETFL);flag = flag | O_NONBLOCK;fcntl(0,F_SETFL,flag);fd_set readfds;FD_ZERO(&readfds);int client_addr[100] = {0};int len = 0;//1、创建套接字int sfd = socket(AF_INET, SOCK_STREAM, 0);//参数1:表示ipv4的网络通信//参数2:表示使用的是TCP通信方式//参数3:表示默认使用一个协议if(sfd == -1){perror("socket error");return -1;}printf("socket success, sfd = %d\n", sfd); //3//将端口号快速重用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))==-1){perror("setsockopt error");return -1;}printf("端口号快速重用成功\n");//2、为套接字绑定ip地址和端口号//2.1 填充地址信息结构体struct sockaddr_in sin; sin.sin_family = AF_INET; //通信域sin.sin_port = htons(SER_PORT); //端口号sin.sin_addr.s_addr = inet_addr(SER_IP); //ip地址//2.2 绑定工作if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1){perror("bind error");return -1;}printf("bind success\n");//3、将套接字设置成被动监听状态if(listen(sfd, 128)==-1){perror("listen error");return -1;}printf("listen success\n");FD_SET(sfd,&readfds);//4、阻塞等待客户端的连接请求//4.1 定义变量用于接收客户端的信息struct sockaddr_in cin; //用于接收地址信息socklen_t addrlen = sizeof(cin); //用于接收长度// struct sockaddr_in Client[128];FD_SET(0,&readfds);char sbuf[128] = "";while(1){fd_set temp = readfds;select(FD_SETSIZE,&temp,0,0,0);if(FD_ISSET(sfd,&temp)){int newfd = accept(sfd,(struct sockaddr*)&cin,&addrlen);printf("有新客户端连接\n");FD_SET(newfd,&readfds);insert_client(client_addr,&len,newfd);}//每一个客户端套接字都要判断是否激活,如果激活了,调用read读取客户端发来的消息for(int i=0;i<len;i++){int client = client_addr[i];if(FD_ISSET(client,&temp)){//客户端套接字激活有两种情况,一种是发来的消息,一种是断开连接char buf[128] = {0};int res = read(client,buf,128);if(res == 0){printf("有客户端断开连接\n");//客户端断开//1.从监视链表删除FD_CLR(client,&readfds);//2.从客户端数组删除remove_client(client_addr,&len,client);//3.关闭套接字close(client);break;}printf("客户端发来消息:%s\n",buf);}}bzero(sbuf,sizeof(sbuf));fgets(sbuf,sizeof(sbuf),stdin);sbuf[strlen(sbuf) - 1] = 0;if(FD_ISSET(0,&temp)){for(int i=0;i<len;i++){int client = client_addr[i];send(client,sbuf,strlen(sbuf),0);}}}//6、关闭监听close(sfd);return 0;
}
客户端
#include<myhead.h>#define SER_PORT 6666 //与服务器保持一致
#define SER_IP "10.80.15.182" //服务器ip地址
#define CLI_PORT 8888 //客户端端口号
#define CLI_IP "10.80.15.182" //客户端ip地址int main(int argc, const char *argv[])
{int flag = fcntl(0,F_GETFL);flag = flag | O_NONBLOCK;fcntl(0,F_SETFL,flag);fd_set readfds;FD_ZERO(&readfds);int client_addr[100] = {0};int len = 0;//1、创建用于通信的套接字文件描述符int cfd = socket(AF_INET, SOCK_STREAM, 0);if(cfd == -1){perror("socket error");return -1;}printf("cfd = %d\n", cfd); //3//2、绑定IP地址和端口号//2.1 填充地址信息结构体struct sockaddr_in cin; cin.sin_family = AF_INET; //通信域cin.sin_port = htons(CLI_PORT); //端口号cin.sin_addr.s_addr = inet_addr(CLI_IP); //ip地址//2.2 绑定工作/*if(bind(cfd, (struct sockaddr*)&cin, sizeof(cin)) == -1){perror("bind error");return -1;}printf("bind success\n");*///3、连接到服务器//3.1 填充服务器地址信息结构体struct sockaddr_in sin;sin.sin_family = AF_INET; //通信域sin.sin_port = htons(SER_PORT); //服务器端口号sin.sin_addr.s_addr = inet_addr(SER_IP); //服务器ip地址//3.2 连接服务器if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) == -1){perror("connect error");return -1;}printf("连接服务器成功\n");FD_SET(cfd,&readfds);FD_SET(0,&readfds);//4、数据收发char buf[128] = "";while(1){fd_set temp = readfds; select(FD_SETSIZE,&temp,0,0,0);if(FD_ISSET(cfd,&temp)){char rbuf[128] = "";int res = recv(cfd,rbuf,sizeof(rbuf),0);if(res == 0){printf("服务器已下线\n");FD_CLR(cfd,&readfds);break;}printf("服务器发来消息:%s\n",rbuf);}bzero(buf,sizeof(buf));fgets(buf, sizeof(buf), stdin); //从终端获取一个字符串if(strlen(buf) != 0){buf[strlen(buf)-1] = 0;}if(FD_ISSET(0,&temp)){send(cfd, buf, strlen(buf),0);printf("发送成功\n");}//接受服务器发来的数据//清空容器/* bzero(buf, sizeof(buf));recv(cfd, buf, sizeof(buf), 0);printf("收到服务器消息为:%s\n", buf);*/}//5、关闭套接字close(cfd);return 0;
}
相关文章:
2024.8.21
作业: 运行1个服务器和2个客户端 实现效果: 服务器和2个客户端互相聊天,服务器和客户端都需要使用select模型去实现 服务器要监视2个客户端是否连接,2个客户端是否发来消息以及服务器自己的标准输入流 客户端要监视服务器是否发来…...
在Ubuntu16.04里安装ROS Kinetic
1.设置apt的source list sudo sh -c echo "deb http://packages.ros.org/ros/ubuntu$(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list 2.设置gpd keys sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365…...
后端开发刷题 | 合并两个排序的链表
描述 输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。 数据范围: 0≤n≤1000,−1000≤节点值≤1000 如输入{1,3,5},{2,4,6}时,合并后的链表为{1,2,3,4,5,6},…...
JAVA_7
JAVA_7 JAVA面向对象编程1. 抽象方法和抽象类 JAVA面向对象编程 1. 抽象方法和抽象类 使用abstract修饰的方法,没有方法体,只有声明。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。包含抽象方法的类就是抽象类。通过…...
最大连续1的个数 III(LeetCode)
题目 给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。 解题 def longestOnes(nums, k):left 0max_len 0zero_count 0for right in range(len(nums)):# 如果遇到0,统计当前窗口内0的个…...
Vue之前端批量下载文件并以压缩包形式存储
后端返回一个文件链接的数组,前端处理下载逻辑,并且将这些文件存储在压缩包内部,这用的jszip 和 file-saver 这两个库。 步骤说明 1.使用 npm 或 yarn 安装 jszip 和 file-saver。 npm install jszip file-saver 2.获取文件内容:…...
【AI学习】LLaMA模型的微调成本有几何?
在前面文章《LLaMA 系列模型的进化(二)》中提到了Stanford Alpaca模型。 Stanford Alpaca 基于LLaMA (7B) 进行微调,通过使用 Self-Instruct 方法借助大语言模型进行自动化的指令生成,Stanford Alpaca 生成了 52K 条指令遵循样例数…...
【专题】2024全数驱动 致胜未来-数字化敏捷银行白皮书报告合集PDF分享(附原数据表)
原文链接: https://tecdat.cn/?p37404 政策明确发展使命,新时代商业银行应坚持党建引领,秉持高质量发展理念。数字经济已成大势,商业银行需构建数字基础设施能力,强化顶层战略规划。当前商业银行数字化发展面临诸多挑…...
280Hz显示器哪家强
280Hz显示器哪家强?今天就给大家带来6大品牌和型号的280Hz显示器一起对比对比! 1.280Hz显示器 - HKC G27H3显示器 HKC G27H3是一款高性价比的电竞显示器,以下是它的一些特点: - **高刷新率与快速响应**: - 拥有280H…...
ROUTE_STATUS
ROUTE_STATUS是一个只读属性,由Vivado路由器分配给网络 反映网络上路由的当前状态。 该属性可以由单个网络或一组网络使用 get_property或report_property命令。该物业由 report_route_status命令返回整个设计的route_status。 架构支持 所有架构。 适用对象 •网络…...
v4l2(video4linux2) yuyv(yuv422)、MJPEG、H.264
V4L2(Video4Linux2)是Linux内核中的视频设备接口框架,专门用于捕获和输出视频数据。V4L2广泛应用于各种视频设备的驱动程序开发,如网络摄像头、电视调谐器、视频采集卡、以及其他视频输入/输出设备。 ### V4L2的主要功能 1. **视…...
.Net插件开发开源框架
在.NET开发中,有许多开源框架可以用于插件开发,以下是一些最常见的框架: MEF(Managed Extensibility Framework) MEF是一个用于创建可插拔软件应用程序的库,它可以在不修改原始应用程序的情况下扩展应用程…...
基于Spark实现大数据量的Node2Vec
基于Spark实现大数据量的Node2Vec Node2Vec 是一种基于图的学习算法,用于生成图中节点的低维度、高质量的向量表示。这种算法基于 word2vec 模型,将自然语言处理中的词嵌入技术应用于图结构的节点,以捕捉节点之间的复杂关系。Node2Vec 特别强…...
[VMware]VMware-Esxi 6.7 厚置备转为精简置备
背景:创建了一个win10 60G的厚置备磁盘,现在想改为精简置备。 先关闭win10系统,并删除快照 1、开启shell 2、登录到虚拟存放的目录 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [rootxxx:~] cd /vmfs/volumes/5fea055e-458157d3-c8f8-8cec4ba51c4…...
vue面试题十八
一、Vue 3中的样式绑定有哪些新特性? Vue 3中的样式绑定保持了与Vue 2相似的灵活性和强大功能,同时引入了一些新的特性和改进,主要集中在响应式系统和Composition API上。以下是Vue 3中样式绑定的主要新特性及其说明: 1. 响应式…...
windows C++-windows C++/CX简介(三)
^类型 (^) 是 C/CX 最突出的功能之一——当人们第一次看到 C/CX 代码时,很难不注意到它。那么,^ 类型到底是什么?这是类型是一种智能指针类型,它自动管理 Windows 运行时对象的生命周期,也 提供自动类型转换功能以简化…...
《黑神话.悟空》:一场跨越神话与现实的深度探索
《黑神话.悟空》:一场跨越神话与现实的深度探索 在国产游戏日益崛起的今天,《黑神话.悟空》以其独特的剧情、丰富的人物设定和深刻的主题,成为了无数玩家翘首以盼的国产3A大作。这款游戏不仅是一次对传统故事的创新演绎,更是一场对…...
【Kotlin设计模式】建造者模式在Android中的应用
前言 建造者模式(Builder Pattern)是一种创建型设计模式,一步一步地构建一个复杂对象的不同部分,而不是直接创建该对象的实例。建造者模式的核心思想是将对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的…...
Kafka 性能为什么比 RocketMQ 好
Kafka 性能更好的原因 因为 kafka 零拷贝技术跟 RocketMQ 的不一样。 kafka 零拷贝技术使用的是 sendfileDMA scatter/gather 。只需要经过 2 次拷贝,2 次上下文切换RocketMQ 零拷贝使用的 mmap 内存映射,需要经过 3 次拷贝,4 次上下文切换…...
el-image的配套使用(表格,表单)
1. 配合table在一起使用,支持预览 此处使用场景是表格中只显示一张图片 preview-src-list只支持数组,故需要将单个字符串转换为转换为字符串数组 <el-table-column align"center" label"二维码"><template slot-scope&q…...
MKS MWH-5匹配器Automatc matching impedance Network手侧
MKS MWH-5匹配器Automatc matching impedance Network手侧...
打卡50天------图论
正式开启图论了,作为一个前端工程师,这个代码随想录真的刷新了我对于算法的认知,每天都在学习新东西。 别着急、放轻松、慢慢来。 一、图论理论基础 二、深搜理论基础 了解一下深搜的原理和过程,其实对于深搜和广搜我自己也写过…...
实现 FastCGI
CGI的由来: 最早的 Web 服务器只能简单地响应浏览器发来的 HTTP 请求,并将存储在服务器上的 HTML 文件返回给浏 览器,也就是静态 html 文件,但是后期随着网站功能增多网站开发也越来越复杂,以至于出现动态技 术&…...
0x01 GlassFish 任意文件读取漏洞复现
参考文章: 应用服务器glassfish任意文件读取漏洞 - SecPulse.COM | 安全脉搏 fofa 搜索使用该服务器的网站 网络空间测绘,网络空间安全搜索引擎,网络空间搜索引擎,安全态势感知 - FOFA网络空间测绘系统 "glassfish"&…...
RLOC_ORIGIN
RLOC_ORIGIN属性为相对放置的对象提供绝对位置或LOC RTL设计中的宏(RPM)。有关定义RPM和使用 RLOC_ORIGIN属性,请参阅《Vivado Design Suite用户指南:使用约束》 (UG903)[参考文献19]。 RPM是通过使用H_set…...
【Python】成功解决 NameError: name ‘reload‘ is not defined
【Python】成功解决 NameError: name ‘reload’ is not defined 下滑即可查看博客内容 🌈 欢迎莅临我的个人主页 👈这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地!🎇 🎓 博主简介:985高校…...
Android.bp和Android.mk文件有的区别
文章目录 1. 构建系统2. 语法和格式3. 可维护性和扩展性4. 编译效率5. 未来趋势 在Android的构建系统中, Android.mk和 android.bp是用于定义如何编译项目文件的两种文件类型,它们有一些显著的区别。 1. 构建系统 Android.mk:使用于基于GN…...
思科设备静态路由实验
拓扑及需求 网络拓扑及 IP 编址如图所示;PC1 及 PC2 使用路由器模拟;在 R1、R2、R3 上配置静态路由,保证全网可达;在 R1、R3 上删掉上一步配置的静态路由,改用默认路由,仍然要求全网可达。 各设备具体配置…...
学习笔记第二十九天
IPC 进程间通信方式:共享内存 原理 共享内存是最高效的进程间通信方式之一,因为它允许两个或多个进程直接访问同一块物理内存区域。这种机制避免了数据在用户空间和内核空间之间的频繁拷贝,从而显著提高了数据传输的效率。 在Linux系统中&…...
Apache Paimon走在正确的道路上|一些使用体验和未来判断
Apache Paimon这个框架大家应该都不陌生了。 在实际工作中大家应该多多少少都用到,这个文章是一个简单的使用体会。不涉及湖框架的拉踩,我们的着眼点是解决实际问题。 我来结合自身体会跟大家说说Paimon这个框架和对未来的一些判断。大家可以参考&#x…...
同企网站建设做网站/百度推广的费用
http://www.yiichina.com/video 转载于:https://www.cnblogs.com/shanyongchen/p/6585733.html...
seo 网站太小/网站网络推广优化
天使的脸庞、魔鬼的声音是一种什么体验?声音和相貌不符的痛苦你不懂…01cedarwood_每次打电话都以为我是男人02鱼嘎尾我睡觉刚起来声音特别粗,有一次我爸打来立马发火问我哪个男人在????? 03哎我…...
创建网站公司 徐州/怎么样推广自己的公司
问题:向正在编辑的Word文档中插入图片时,会发现图片只显示了部分,其余部分被其上面的问题遮挡住 原因:可能是由于设置固定的行间距,导致图片被遮挡 解决方法: 选定插入的图片,在菜单栏中找到 “…...
dz网站建设/网站seo方案策划书
三 Controller1. 常用注解 Controller 接收http请求 RestController 是Controller和ResponseBody的结合 RequestMapping url地址映射 PathVariable 获取url参数 RequestParam 获取请求参数的值 GetMapping 组合注解 简化get方法 2. 模板配置 在resources目录下新建temp…...
网络营销模式下品牌推广研究论文/谷歌网站优化
chage命令_Linux chage命令使用详解:修改帐号与密码的有效期限chage命令是用来修改帐号与密码的有效期限。语法:chage [选项] 用户名。选项:-m:密码可更改的最小天数。为零时代表任何时候都可以更改密码。-M:密码保持有…...
2019建一个什么网站最好/上海seo培训中心
php的重定向,很简单,除去直接打印出重定向的JavaScript代码以外, 使用原生态的php重定向是这样的: <?php header("location: url"); exit; ?>一读到这条语句则会马上跳转到指定的重定向url。当然,P…...