UDP网络聊天室(更)

服务器端

#include <header.h>
typedef struct node
{char name[20];struct sockaddr_in cli_addr;struct node *next;
}node,*node_p;
typedef struct msg
{char type;char name[20];char text[128];
}msg;
node_p create_link()
{node_p H=(node_p)malloc(sizeof(node));if(H==NULL){printf("apply fail\n");return NULL;}H->next=NULL;return H;
}
node_p create_node(char *name,struct sockaddr_in cli_addr)
{node_p new=(node_p)malloc(sizeof(node));if(new==NULL){printf("apply fail\n");return NULL;}strcpy(new->name,name);new->cli_addr=cli_addr;new->next=NULL;return new;
}
void insert(node_p H,char *name,struct sockaddr_in cli_addr)
{if(H==NULL){printf("apply fail\n");return;}node_p new=create_node(name,cli_addr);new->next=H->next;H->next=new;
}
void delete(node_p H,char* name)
{if(H==NULL){printf("apply fail\n");return;}node_p p=H->next;while(p!=NULL&&strcmp(p->next->name,name)!=0){p=p->next;}node_p p1=p->next;p->next=p->next->next;free(p1);
}
int main(int argc, const char *argv[])
{if(argc!=3){printf("请依次输入正确的ip地址和端口号!\n");return 1;}const char *SER_IP=argv[1];int SER_PORT=atoi(argv[2]);int sfd=socket(AF_INET,SOCK_DGRAM,0);               if(sfd==-1){perror("socket");return 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);if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("bind");return 1;}struct sockaddr_in cin;socklen_t addrlen=sizeof(cin);char wbuf[128]={0};struct pollfd pfd[2];pfd[0].fd=sfd;pfd[1].fd=0;pfd[0].events=POLLIN;pfd[1].events=POLLIN;node_p H=create_link();msg msg;printf("等待用户加入....\n");while(1){int res=poll(pfd,2,-1);if(res==-1){perror("poll");return 1;}else if(res==0){printf("time out\n");return 1;}if(pfd[0].revents==POLLIN){memset(&msg,0,sizeof(msg));recvfrom(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&cin,&addrlen);if(msg.type=='n'){node_p p=H->next;insert(H,msg.name,cin);printf("*********\033[1;35m[%s\033[0m:\033[1;32m%d] \033[33m %s\033[0m\033[1;36m 已进入聊天室\033[0m*********** \n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),msg.name);while(p!=NULL){sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&p->cli_addr,sizeof(p->cli_addr));p=p->next;}}else if(msg.type=='t'){node_p p=H->next;printf("%s:%s\n",msg.name,msg.text);while(p!=NULL){msg.type='t';if(strcmp(p->name,msg.name)!=0){sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&p->cli_addr,sizeof(p->cli_addr));}p=p->next;}}else if(msg.type=='q'){printf("\033[1;36m%s离开了聊天室...\n",msg.name);node_p p=H->next;while(p!=NULL){msg.type='q';sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&p->cli_addr,sizeof(p->cli_addr));p=p->next;}}}if(pfd[1].revents==POLLIN){msg.type='s';bzero(wbuf,sizeof(wbuf));fgets(wbuf,sizeof(wbuf),stdin);strcpy(msg.text,wbuf);msg.text[strlen(msg.text)-1]=0;node_p p=H->next;while(p!=NULL){msg.type='s';sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&p->cli_addr,sizeof(p->cli_addr));p=p->next;}printf("\033[1;36m系统消息推送成功。\n");}}close(sfd);return 0;
}

客户端

#include <header.h>
int quit_flag=0;
typedef struct msg
{char type;char name[20];char text[128];
}msg;
int main(int argc, const char *argv[])
{if(argc!=3){printf("\033[1;35m请依次输入正确的ip地址和端口号!\n");return 1;}const char *SER_IP=argv[1];int SER_PORT=atoi(argv[2]);printf("\033[1;36m请输入用户名:");int cfd=socket(AF_INET,SOCK_DGRAM,0);if(cfd==-1){perror("socket");return 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);socklen_t addrlen=sizeof(sin);struct pollfd pfd[2];   pfd[0].fd=0;pfd[1].fd=cfd;pfd[0].events=POLLIN;pfd[1].events=POLLIN;msg msg;char username[20]={0};fgets(username,sizeof(username),stdin);strcpy(msg.name,username);msg.name[strlen(msg.name)-1]=0;msg.type='n';sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin));char rbuf[128]={0};while(1){int res=poll(pfd,2,-1);if(res==-1){perror("poll");return 1;}else if(res==0){printf("time out\n");return 1;}if(pfd[0].revents==POLLIN){msg.type='t';strcpy(msg.name,username);msg.name[strlen(msg.name)-1]=0;char txt[128]={0};bzero(txt,sizeof(txt));fgets(txt,sizeof(txt),stdin);strcpy(msg.text,txt);msg.text[strlen(msg.text)-1]=0;int flag=0;if(strcmp(msg.text,"quit")==0){msg.type='q';sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin));flag=1;quit_flag=1;}if(flag==0){sendto(cfd,&msg,sizeof(msg),MSG_DONTWAIT,(struct sockaddr*)&sin,sizeof(sin));}}if(pfd[1].revents==POLLIN){recvfrom(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,&addrlen);if(msg.type=='t'){printf("\033[1;34m%s:\033[0m%s\n",msg.name,msg.text);}else if(msg.type=='n'){printf("-----------------\033[1;33m %s \033[1;35m 已上线 \033[1;33m--------------\n",msg.name);}else if(msg.type=='s'){printf("\033[1;36msystem:%s\n",msg.text);}else if(msg.type=='q'){printf("-----------------\033[1;33m %s\033[1;35m  已下线 \033[1;33m-------------\n",msg.name);if(quit_flag==1){break;}}}}close(cfd);exit(0);return 0;
}

功能实现

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

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

相关文章

Excel超级表的注意事项

#Excel&#xff0c;插入&#xff0c;表格。即得到一张“超级表”。实际上它才是真正意义上的Excel表格&#xff0c;我们平时所使用的表格&#xff0c;其实是一块区域。表格是一个整体&#xff0c;而区域的范围是可以蔓延的。 计算的字段在新增内容时&#xff0c;是会自动填充的…

使用Selenium获取框架内网页源码

使用Selenium获取框架内网页源码 要使用Selenium获取框架内的网页源码&#xff0c;您可以按照以下步骤操作&#xff1a; 首先&#xff0c;确保您已经安装了Selenium库以及对应的WebDriver。例如&#xff0c;如果您使用的是Chrome浏览器&#xff0c;则需要下载ChromeDriver。 …

网络业务创新驱动下的DPU P4技术,中科驭数在网络开源技术生态大会上分享最新进展

2024年5月25日&#xff0c;由中国通信学会指导&#xff0c;中国通信学会开源技术专业委员会、江苏省未来网络创新研究院主办的第四届网络开源技术生态大会在北京举办&#xff0c;中科驭数产品总监李冬以《合作如兰&#xff0c;扬扬其香 中科驭数助力P4产业发展与生态建设》为主…

React hooks - 自定义hooks

自定义hooks 自定义封装鼠标位置的 hook自定义封装秒数倒计时的 hook 在 src 目录下新建 hooks/index.ts 模块&#xff0c;自定义hooks都写在这里&#xff0c;自定义hooks都以use开头 自定义封装鼠标位置的 hook export const useMousePosition (delay:number 0) > {cons…

Java中的注解(Annotation)是什么?它们有什么用途?

技术难点 在Java中&#xff0c;注解&#xff08;Annotation&#xff09;是一种元数据&#xff08;metadata&#xff09;的形式&#xff0c;用于为Java代码&#xff08;类、方法、变量、参数和包等&#xff09;提供额外的信息。这些信息在运行时可以通过反射机制进行读取和处理…

Cweek2+3

C语言学习 五.操作符 5.单目操作符(2) sizeof不能用于计算动态分配的内存 在对数组使用sizeof时&#xff0c;返回的是整个数组的大小&#xff08;所有元素的总字节数&#xff09;。而对指针使用sizeof时&#xff0c;返回的是指针本身的大小&#xff08;通常是机器字长的大小…

uniapp配置跨域问题

在vue2中可以在manifest.json中的devServer里设置 在vue3中需要在vite.config.ts(vite.config.js)中的defineConfig中添加代理设置 export default defineConfig({....,server: {proxy: {/api: {target: http://127.0.0.1:8989,changeOrigin:true,rewrite:(path)>path.rep…

怎么简单的把图片缩小?图片在线改大小的方法

在日常工作中经常需要在网上上传图片&#xff0c;但是一般网上不同的平台对上传的图片大小和尺寸都会有限定的要求&#xff0c;不符合要求无法正常上传使用。所以当遇到图片太大的问题时&#xff0c;该如何快速修改图片大小&#xff0c;有很多的小伙伴都很关注这个问题的解决方…

【Qt秘籍】[002]-开始你的Qt之旅-下载

一、Qt的开发工具有哪些&#xff1f; Qt的开发工具概述Qt支持多种开发工具&#xff0c;其中最常见的开发工具是 1.QtCreator 【易上手/有少量bug/适合新手】 2.VisualStudio 【功能强大/易出错/需要更多额外配置】 3.Eclipse 【清朝老兵IDE/不建议使用】 【注意&#xff1…

【第三节】类的构造和析构函数

目录 一、数据成员的初始化 二、构造函数 2.1 什么是构造函数 2.2 构造函数的注意事项 三、析构函数 四、带参数的构造函数 五、缺省构造函数 六、构造函数初始化列表 七、拷贝构造函数和调用规则 八、深拷贝和浅拷贝 九、总结 一、数据成员的初始化 定义普通变量&am…

基于BP神经网络和小波变换特征提取的烟草香型分类算法matlab仿真,分为浓香型,清香型和中间香型

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ...................................................................................... …

深入探究Java自动拆箱与装箱的实现原理

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

AOSP之编译adb

adb指令原理网上很多帖子&#xff0c;这里不再赘述 在AOSP中&#xff0c;adb的源码路径在system/core/adb目录下&#xff0c;当我们需要修改adb文件&#xff0c;加入或者删改一些内容的时候就需要修改这个路径下的文件&#xff0c;那么如何编译和替换测试 1.编译&#xff1a; …

Linux:进程控制(二.详细讲解进程程序替换)

上次讲了&#xff1a;Linux&#xff1a;进程地址空间、进程控制&#xff08;一.进程创建、进程终止、进程等待&#xff09; 文章目录 1.进程程序替换1.1概念1.2原理1.3使用一个exec 系列函数execl&#xff08;&#xff09;函数结论与细节 2.多进程时的程序替换3.其他几个exec系…

mysql连接池的实现

概要&#xff1a;本文介绍mysql连接池的实现&#xff0c;要求读者了解线程池 一、为什么需要mysql连接池&#xff1f; 资源复用 &#xff1a;不使用连接池&#xff0c;每次数据库请求都新建一条连接&#xff0c;将耗费系 统资源。 流程如下&#xff1a; 通过三次握手建立 TC…

大数据面试题 —— Hive

目录 Hive 是什么为什么要使用 HiveHive 的优缺点Hive的实现逻辑&#xff0c;为什么处理小表延迟比较高你可以说一下 HQL 转换为 MR 的任务流程吗 ***你可以说一下 hive 的元数据保存在哪里吗 ***Hive与传统数据库之间的区别Hive内部表和外部表的区别 ***hive 动态分区与静态分…

Hotcoin Research | 市场洞察:2024年5月13日-5月19日

加密货币市场表现 目前&#xff0c;加密货币总市值为1.32万亿&#xff0c;BTC占比54.41%。 本周行情呈现震荡上行的态势&#xff0c;BTC在5月15日-16日&#xff0c;有一波大的拉升&#xff0c;周末为震荡行情。BTC现价为67125美元。 上涨的主要原因&#xff1a;美国4月CPI为3…

效率工作:一键为多种资产添加统一材质(小插件)

1.需求分析&#xff1a; 当导入一批资产&#xff0c;或者有同一批结构体需要添加相同材质时&#xff0c;单独为每个模型都添加材质费时费力&#xff0c;有没有什么办法&#xff0c;能同时为多个资产添加材质。 2.操作实现 1.在网上找到了一款插件&#xff0c;经过验证&#xf…

如何将天猫内容保存为PDF格式?详细步骤与实战解析

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;保存天猫内容的重要性 二、环境准备与工具安装 1. 安装必要的Python包…

基于接口而非实现编程:有没有必要为每个类都定义接口

目录 1.引言 2.接口的多种理解方式 3.设计思想实战应用 4.避免滥用接口 5.思考题 1.引言 本节介绍一种与“接口”相关的设计思想;基于接口而非实现编程&#xff0c;它非常重要且在平时的开发中经常被用到。 2.接口的多种理解方式 “基于接口而非实现编程”设计思想的英文…