项目篇:基于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

相关文章

SpringBoot项目中报错The field screenShot exceeds its maximum permitted size of 1048576 bytes.的问题及解决

《SpringBoot项目中报错ThefieldscreenShotexceedsitsmaximumpermittedsizeof1048576bytes.的问题及解决》这篇文章... 目录项目场景问题描述原因分析解决方案总结项目场景javascript提示:项目相关背景:项目场景:基于Spring

解决Maven项目idea找不到本地仓库jar包问题以及使用mvn install:install-file

《解决Maven项目idea找不到本地仓库jar包问题以及使用mvninstall:install-file》:本文主要介绍解决Maven项目idea找不到本地仓库jar包问题以及使用mvnin... 目录Maven项目idea找不到本地仓库jar包以及使用mvn install:install-file基

springboot项目如何开启https服务

《springboot项目如何开启https服务》:本文主要介绍springboot项目如何开启https服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录springboot项目开启https服务1. 生成SSL证书密钥库使用keytool生成自签名证书将

将Java项目提交到云服务器的流程步骤

《将Java项目提交到云服务器的流程步骤》所谓将项目提交到云服务器即将你的项目打成一个jar包然后提交到云服务器即可,因此我们需要准备服务器环境为:Linux+JDK+MariDB(MySQL)+Gi... 目录1. 安装 jdk1.1 查看 jdk 版本1.2 下载 jdk2. 安装 mariadb(my

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/

springboot项目中常用的工具类和api详解

《springboot项目中常用的工具类和api详解》在SpringBoot项目中,开发者通常会依赖一些工具类和API来简化开发、提高效率,以下是一些常用的工具类及其典型应用场景,涵盖Spring原生... 目录1. Spring Framework 自带工具类(1) StringUtils(2) Coll

Spring Boot项目部署命令java -jar的各种参数及作用详解

《SpringBoot项目部署命令java-jar的各种参数及作用详解》:本文主要介绍SpringBoot项目部署命令java-jar的各种参数及作用的相关资料,包括设置内存大小、垃圾回收... 目录前言一、基础命令结构二、常见的 Java 命令参数1. 设置内存大小2. 配置垃圾回收器3. 配置线程栈大小

Spring Boot项目中结合MyBatis实现MySQL的自动主从切换功能

《SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能》:本文主要介绍SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能,本文分步骤给大家介绍的... 目录原理解析1. mysql主从复制(Master-Slave Replication)2. 读写分离3.

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.