网络聊天室项目

服务器端

#include <myhd.h>//传输结构体
struct cli
{char type;    //  L/C/Qchar name[20];char text[128];
};
int main(int argc, const char *argv[])
{if(argc!=3){printf("请输入ip地址和端口号\n");return -1;}//1、创建用于通信的套接字文件描述符int sfd=socket(AF_INET,SOCK_DGRAM,0);if(sfd==-1){perror("socket error");return -1;}printf("socket success sfd=%d\n",sfd);//设置端口号快速重用int reuse=1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){perror("setsockopt error");return -1;}printf("设置端口重用成功\n");//2、绑定//2.1、填充服务器信息结构体struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(atoi(argv[2]));sin.sin_addr.s_addr=inet_addr(argv[1]);//2.2、绑定工作if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("bind error");return -1;}printf("bind success\n");//填充客户端信息结构体struct sockaddr_in cin[1024];struct sockaddr_in cintemp;cintemp.sin_family=AF_INET;socklen_t socklen=sizeof(cintemp);//定义用于检测文件描述符的集合fd_set readfds,tempfds;//清空容器中的内容FD_ZERO(&readfds);//将要检测的文件描述符放入集合中FD_SET(sfd,&readfds);FD_SET(0,&readfds);//用于存放客户昵称等信息struct cli msg[1024];struct cli temp;//清空结构体数组for(int i=0;i<1024;i++){bzero(msg[i].name,sizeof(msg[0].name));bzero(msg[i].text,sizeof(msg[0].text));}char buf[128]="";int res=0;  //接收select的返回值int maxi=-1;  //群聊成员个数while(1){//复制一份tempfds=readfds;//使用select阻塞等待集合中的文件描述符res=select(sfd+1,&tempfds,NULL,NULL,NULL);if(res==-1){perror("select error");return -1;}else if(res==0){printf("time out\n");return -1;}if(FD_ISSET(sfd,&tempfds)){//清空内容temp.type=0;bzero(temp.name,sizeof(temp.name));bzero(temp.text,sizeof(temp.text));recvfrom(sfd,&temp,sizeof(temp),0,(struct sockaddr*)&cintemp,&socklen);if(temp.type=='l'||temp.type=='L')  //登录{printf("%s[%s:%d]:登录成功\n",temp.name,inet_ntoa(cintemp.sin_addr),ntohs(cintemp.sin_port));maxi++;strcpy(msg[maxi].name,temp.name);cin[maxi].sin_port=cintemp.sin_port;cin[maxi].sin_addr.s_addr=cintemp.sin_addr.s_addr;for(int j=0;j<=maxi;j++){if(cintemp.sin_port==cin[j].sin_port){continue;}sendto(sfd,&temp,sizeof(temp),0,(struct sockaddr*)&cin[j],sizeof(cin[j]));}}if(temp.type=='c'||temp.type=='C')  //聊天{printf("%s发送了一条消息\n",temp.name);for(int j=0;j<=maxi;j++){if(cintemp.sin_port==cin[j].sin_port){continue;}sendto(sfd,&temp,sizeof(temp),0,(struct sockaddr*)&cin[j],sizeof(cin[j]));}}if(temp.type=='q'||temp.type=='Q')  //退出协议{int i=0;if(strcmp(temp.text,"quit")==0){strcpy(temp.name,msg[i].name);}printf("%s[%s:%d]:已离线\n",temp.name,inet_ntoa(cintemp.sin_addr),ntohs(cintemp.sin_port));for(i=0;i<=maxi;i++){if(cintemp.sin_port==cin[i].sin_port){int t=i;for(int j=maxi;j>=i;j--){cin[t]=cin[t+1];msg[t]=msg[t+1];t++;}maxi--;}sendto(sfd,&temp,sizeof(temp),0,(struct sockaddr*)&cin[i],sizeof(cin[i]));}}}if(FD_ISSET(0,&tempfds)){bzero(buf,sizeof(buf));fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';if(strcmp(buf,"quit")==0){close(sfd);return 0;}temp.type='C';strcpy(temp.text,buf);strcpy(temp.name,"***system***");for(int i=0;i<=maxi;i++){sendto(sfd,&temp,sizeof(temp),0,(struct sockaddr*)&cin[i],sizeof(cin[i]));}}}//5、关闭套接字文件描述符close(sfd);return 0;
}

客户端

#include <myhd.h>//传输结构体
struct cli
{char type;  //  L/C/Q协议char name[20];char text[128];
};
int main(int argc, const char *argv[])
{if(argc!=3){printf("请输入服务器和端口号\n");return -1;}//创建昵称char n_name[20]="";printf("请输入昵称:");scanf("%s",n_name);getchar();//1、创建客户端套接字文件描述符int cfd=socket(AF_INET,SOCK_DGRAM,0);if(cfd<0){perror("socket error");return -1;}printf("socket success cfd=%d\n",cfd);//填充服务器端信息结构体struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(atoi(argv[2]));sin.sin_addr.s_addr=inet_addr(argv[1]);socklen_t socklen=sizeof(sin);char buf[128]="";char rbuf[128]="";int res=0; //检测select//定义用于检测文件描述符的集合fd_set readfds,tempfds;//清空容器中的内容FD_ZERO(&readfds);//将要检测的文件描述符放入集合中FD_SET(cfd,&readfds);FD_SET(0,&readfds);//创建客户端的同时,向服务器发送一个L协议的结构体struct cli cmsg;cmsg.type='L';strcpy(cmsg.name,n_name);sendto(cfd,&cmsg,sizeof(cmsg),0,(struct sockaddr*)&sin,sizeof(sin));//2、收发数据while(1){//复制一份tempfds=readfds;//使用select阻塞等待集合中的文件描述符res=select(cfd+1,&tempfds,NULL,NULL,NULL);if(res==-1){perror("select error");return -1;}else if(res==0){printf("time out\n");return -1;}if(FD_ISSET(0,&tempfds)){bzero(buf,sizeof(buf));fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';if(strcmp(buf,"quit")==0){cmsg.type='Q';strcpy(cmsg.name,n_name);sendto(cfd,&cmsg,sizeof(cmsg),0,(struct sockaddr*)&sin,sizeof(sin));close(cfd);return 0;}else{strcpy(cmsg.name,n_name);strcpy(cmsg.text,buf);cmsg.type='C';sendto(cfd,&cmsg,sizeof(cmsg),0,(struct sockaddr*)&sin,sizeof(sin));}}if(FD_ISSET(cfd,&tempfds)){bzero(buf,sizeof(buf));bzero(rbuf,sizeof(rbuf));recvfrom(cfd,&cmsg,sizeof(cmsg),0,NULL,NULL);if(cmsg.type=='L'){printf("-----%s登陆成功-----\n",cmsg.name);}if(cmsg.type=='Q'){printf("-----%s已离线-----\n",cmsg.name);}if(cmsg.type=='C'){strcpy(buf,cmsg.text);strcpy(rbuf,cmsg.name);printf("%s:%s\n",rbuf,buf);if(strcmp(cmsg.name,"***system***")){strcpy(cmsg.name,n_name);}}}}//4、关闭套接字文件描述符close(cfd);return 0;
}

结果演示

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

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

相关文章

java第二十章总结多线程

20.2创建线程 20.2.1继承Thread类 Thread类是Java.lang包中的一个类&#xff0c;从这个类中实例化的对象代表线程&#xff0c;程序员启动一个新线程需要建议Thread实例。 public class ThreadTest extedns Thread{} run方法格式&#xff1a; public void run(){} 20.1让线程…

MyBatis教程之获取参数值的两种方式(五)

MyBatis获取参数值的两种方式&#xff1a;${} 和 #{} ${} 的本质就是字符串拼接&#xff0c;#{} 的本质就是占位符赋值 ${} 使用字符串拼接的方式拼接sql&#xff0c;若为字符串类型或日期类型的字段进行赋值时&#xff0c;需要手动加单引号&#xff1b;但是 #{} 使用占位符赋…

Attacking Fake News Detectors via Manipulating News Social Engagement(2023 WWW)

Attacking Fake News Detectors via Manipulating News Social Engagement----《通过操纵新闻社交互动来攻击假新闻检测器》 摘要 在年轻一代中&#xff0c;获取新闻的主要来源之一是社交媒体。随着新闻在各种社交媒体平台上日益流行&#xff0c;虚假信息和毫无根据的言论的传…

网络安全应该怎么学?(0基础小白)

一、网络安全应该怎么学&#xff1f; 1.计算机基础需要过关 这一步跟网安关系暂时不大&#xff0c;是进入it行业每个人都必须掌握的基础能力。 计算机网络计算机操作系统算法与数据架构数据库 Tips:不用非要钻研至非常精通&#xff0c;可以与学习其他课程同步进行。 2.渗透技…

钢贸行业ERP系统:实现全面管理与持续增长的利器

去年在上海举办的数字化钢贸高峰论坛中提出钢贸业亟需数字化转型&#xff0c;因为在大力发展数字经济的时代背景下&#xff0c;行业进行数字化转型已经成为一种必然趋势。在今年以前&#xff0c;一些钢贸商一直沿用着以前非常粗放的管理手段&#xff0c;比如手写账本。而如果使…

vr智慧党建展厅超强参与感增强党员群众认同感、归属感

党建教育与VR虚拟现实技术的结合&#xff0c;是顺应现代信息化发展趋势的要求&#xff0c;不仅打破了传统党建教育的束缚&#xff0c;还丰富了党建宣传教育的渠道&#xff0c;党建教育VR云课堂平台是基于深圳华锐视点自主研发的VR云课堂平台中去体验各种VR党建教育软件或者视频…

Go语言实现大模型分词器tokenizer

文章目录 前言核心结构体定义构造函数文本初始处理组词构建词组索引训练数据编码解码打印状态信息运行效果总结 前言 大模型的tokenizer用于将原始文本输入转化为模型可处理的输入形式。tokenizer将文本分割成单词、子词或字符&#xff0c;并将其编码为数字表示。大模型的toke…

记录一下npm包的关键字段

module: 字段指定了 ES 模块版本的入口文件路径&#xff0c;main: 字段则指定了 CommonJS 模块版本的入口文件路径。 注意&#xff1a;尽管 module 字段在构建工具中被广泛支持&#xff0c;但它并不是所有 JavaScript 环境都遵循的规范。在 Node.js 中&#xff0c;通常使用 mai…

【广州华锐视点】VR模拟法庭审判实训,零距离感受庭审全过程

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术已经逐渐渗透到各个领域&#xff0c;为人们提供了全新的体验方式。在法律领域&#xff0c;VR技术的应用也日益受到关注。近年来&#xff0c;越来越多的法学院和培训机构开始尝试将VR技术引入模拟法庭实践…

电商数据采集中如何采集1688平台商品详情SKU数据

一、背景介绍 1688.com是阿里旗下国内最大的B2B批发采购平台&#xff0c;1688分销客是依托此平台的官方营销平台&#xff0c;通过此平台API接口的接入推广平台商家的商品&#xff0c;按照商品成交金额的一定比例获得佣金。可以调用1688平台上的商品详情&#xff0c;SKU数据&…

社区内涝积水监测系统作用,改善社区积水

随着社区化进程的加速&#xff0c;社区基础设施的重要性日益凸显。在这个背景下&#xff0c;社区生命线和内涝积水监测系统成为了关注的焦点。它们在维护社区安全&#xff0c;特别是在应对暴雨等极端天气条件下&#xff0c;发挥着至关重要的作用。 WITBEE万宾时刻关注社区内涝积…

PCL 最小二乘拟合圆柱(C++详细过程版)

目录 一、算法原理1、算法简介2、参考文献二、代码实现三、结果展示四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、算法简介 圆柱拟合步骤主要包括两步: 一是确定柱面模型参数初始值…

关于大模型在文本分类上的尝试

文章目录 前言所做的尝试总结前言 总共25个类别,在BERT上的效果是48%,数据存在不平衡的情况,训练数据分布如下: 训练数据不多,4000左右 所做的尝试 1、基于 Qwen-14b-base 做Lora SFT,Loss忘记记录 准确率在68%左右 Lora配置 class LoraArguments:lora_r: int = 64…

使用机器学习方法进行分析和处理:对高质量图像进行压缩

使用SVD&#xff08;奇异值分解&#xff09;进行图像压缩与普通压缩工具压缩的主要区别在于压缩原理和压缩效果。 压缩原理&#xff1a; 普通图像压缩工具通常采用有损压缩或无损压缩算法&#xff0c;如JPEG、PNG等&#xff0c;它们主要针对图像的像素进行变换和编码。而SVD图像…

算法高频题目

LRUCache实现 思路&#xff1a;使用linkedHashMap。按照插入顺序的有序链表。 get 操作。cache不包含&#xff0c;返回-1。包含。我们需要当前key重新put。 /将 key 变为最近使用 put。如果包含。修改当前key值。然后将key变成最近使用。不包含。如果cacheSize大于当前最大size…

[cocos creator] Label设置为RESIZE_HEIGHT,获取height

问题描述&#xff1a; 需要在scrollview 中显示item, item的高度由子节点label的高度动态决定&#xff0c;但更改string后&#xff0c;获取label的高度仍为初始值。 解决办法&#xff1a; //改变string内容 node.getComponent(Label).string str; //加上这一句 node.getCom…

【JavaEE初阶】volatile 关键字、wait 和 notify

目录 一、volatile 关键字 1、volatile 能保证内存可见性 2、volatile 不保证原子性 二、wait 和 notify 1、wait()方法 2、notify()方法 3、notifyAll()方法 4、wait 和 sleep 的对比 一、volatile 关键字 1、volatile 能保证内存可见性 我们前面的线程安全文章中&…

Docker安装可视化工具Portainer

目录 Portainer简介 Portainer安装 Portainer简介 Portainer是一款开源的容器管理平台&#xff0c;支持多种容器技术&#xff0c;如Docker、Kubernetes和Swarm等。它提供了一个易于使用的Web UI界面&#xff0c;可用于管理和监控容器和集群。Portainer旨在使容器管理更加简单…

前端三大MV*模式:MVC、mvvm、mvp模式介绍

MVC&#xff08;同步通信为主&#xff09;&#xff1a;Model、View、Controller MVP(异步通信为主)&#xff1a;Model、View、Presenter MVVM(异步通信为主)&#xff1a;Model、View、ViewModel mvc模式介绍 MVC&#xff08;Model–View–Controller&#xff09;模式是软件…

Elk:filebeat 日志收集工具和logstash

Elk:filebeat 日志收集工具和logstash Filebeat是一个轻量级的日志手机工具,所使用的系统资源比logstash部署和启动时使用的资源要小得多 Filebeat可以在非java环境使用&#xff0c;他可以代理logstash在非java环境上收集日志 缺点 Filebeat无法实现数据的过滤,一般是结合l…