项目篇:基于UDP通信模型的网络聊天室

2024-01-21 23:52

本文主要是介绍项目篇:基于UDP通信模型的网络聊天室,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

思维导图

基于UDP通信模型的网络聊天室

消息分类及数据包结构

服务器端

#include <head.h>
#define SER_PORT 8888
#define SER_IP "192.168.232.133"
typedef struct mb
{struct sockaddr_in cin;char name[20];struct mb *next;
}*member;
//群发消息
int send_to_all(int sfd,member head,const char *buf,size_t length)
{member p=head;while(p!=NULL){sendto(sfd,buf,length,0,(struct sockaddr*)&(p->cin),sizeof(p->cin));p=p->next;}return 0;
}
//增加成员
member add_member(member head,const char *data,struct sockaddr_in cin)
{member p=(member)malloc(sizeof(struct mb));p->cin=cin;strcpy(p->name,data);p->next=head;head=p;return head;
}
//删除成员
member del_member(member head,const char *name_point)
{member p=head;if(strcmp(p->name,name_point)==0){head=p->next;free(p);p=NULL;return head;}while(strcmp(p->name,name_point)!=0){p=p->next;}if(p->next==NULL){member q=head;while(q->next->next!=NULL){q=q->next;}free(p);p=NULL;q->next=NULL;return head;}member q=head;while(strcmp(q->next->name,name_point)!=0){q=q->next;}q->next=p->next;free(p);p=NULL;return head;
}int main(int argc, const char *argv[])
{int sfd=socket(AF_INET,SOCK_DGRAM,0);if(sfd==-1){perror("socket error:");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 error:");return -1;}struct sockaddr_in cin;socklen_t socklen=sizeof(cin);printf("bind success\n");struct pollfd pfd[1024];pfd[0].fd=0;pfd[0].events=POLLIN;pfd[1].fd=sfd;pfd[1].events=POLLIN;int n=2;member head=NULL;while(1){int res=poll(pfd,n,-1);if(res==-1){perror("poll error:");return -1;}else if(res==0){printf("manbaout\n");return -1;}if(pfd[0].revents==POLLIN){//系统发送消息char buf[128]="";scanf("%s",buf);char sys_buf[200];sprintf(sys_buf,"***system***>>>%s",buf);send_to_all(sfd,head,sys_buf,sizeof(sys_buf));printf("系统发送消息\n");}if(pfd[1].revents==POLLIN){//接收消息char buf[200]="";recvfrom(pfd[1].fd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&socklen);short *type_point = (short*)buf;switch(ntohs(*type_point)){case 1:{//接收到登录的消息char *data_point = buf+2;char buf[300]="";sprintf(buf,"**********%s已登录**********",data_point);send_to_all(sfd,head,buf,sizeof(buf));head=add_member(head,data_point,cin);printf("%s登录\n",data_point);break;}case 2:{//接收到普通的消息char *name_point=buf+2;char *data_point=name_point+strlen(name_point)+1;char buf[300]="";sprintf(buf,"%s>>>%s",name_point,data_point);send_to_all(sfd,head,buf,sizeof(buf));printf("%s发送消息\n",name_point);break;}case 3:{//接收到退出消息char *name_point=buf+2;char *data_point=name_point+strlen(name_point)+1;char endbuf[20]="";strcpy(endbuf,"quit");sendto(sfd,endbuf,sizeof(endbuf),0,(struct sockaddr*)&cin,sizeof(cin));del_member(head,name_point);char buf[300]="";sprintf(buf,"**********%s已下线**********",name_point);send_to_all(sfd,head,buf,sizeof(buf));printf("%s下线\n",name_point);break;}}}}close(sfd);return 0;
}

客户端

#include <head.h>
#define SER_PORT 8888
#define SER_IP "192.168.232.133"int login(int sfd,struct sockaddr_in sin,const char *name)
{char buf[200]="";short *type_point = (short*)buf;char *data_point = buf+2;*type_point=htons(1);strcpy(data_point,name);sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin));return 0;
}
int main(int argc, const char *argv[])
{int sfd=socket(AF_INET,SOCK_DGRAM,0);if(sfd==-1){perror("socket error:");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 socklen;printf("====================欢迎使用网络聊天室====================\n");printf("请输入姓名:");char name[20];scanf("%s",name);login(sfd,sin,name);pid_t pid;pid=fork();if(pid>0){//父进程,用于发消息char buf[128]="";short *type_point = (short*)buf;char *name_point = buf+2;strcpy(name_point,name);char *data_point=name_point+strlen(name_point)+1;while(1){scanf("%s",data_point);if(strcmp(data_point,"quit")==0){*type_point=htons(3);sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin));break;}*type_point=htons(2);sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin));}}else if(pid==0){//子进程,用于接收消息while(1){char buf[128];recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&socklen);if(strcmp(buf,"quit")==0){break;}printf("%s\n",buf);}}wait(NULL);close(sfd);return 0;
}

这篇关于项目篇:基于UDP通信模型的网络聊天室的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/631219

相关文章

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

SpringBoot项目注入 traceId 追踪整个请求的日志链路(过程详解)

《SpringBoot项目注入traceId追踪整个请求的日志链路(过程详解)》本文介绍了如何在单体SpringBoot项目中通过手动实现过滤器或拦截器来注入traceId,以追踪整个请求的日志链... SpringBoot项目注入 traceId 来追踪整个请求的日志链路,有了 traceId, 我们在排

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

配置springboot项目动静分离打包分离lib方式

《配置springboot项目动静分离打包分离lib方式》本文介绍了如何将SpringBoot工程中的静态资源和配置文件分离出来,以减少jar包大小,方便修改配置文件,通过在jar包同级目录创建co... 目录前言1、分离配置文件原理2、pom文件配置3、使用package命令打包4、总结前言默认情况下,

python实现简易SSL的项目实践

《python实现简易SSL的项目实践》本文主要介绍了python实现简易SSL的项目实践,包括CA.py、server.py和client.py三个模块,文中通过示例代码介绍的非常详细,对大家的学习... 目录运行环境运行前准备程序实现与流程说明运行截图代码CA.pyclient.pyserver.py参

IDEA运行spring项目时,控制台未出现的解决方案

《IDEA运行spring项目时,控制台未出现的解决方案》文章总结了在使用IDEA运行代码时,控制台未出现的问题和解决方案,问题可能是由于点击图标或重启IDEA后控制台仍未显示,解决方案提供了解决方法... 目录问题分析解决方案总结问题js使用IDEA,点击运行按钮,运行结束,但控制台未出现http://

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下