C语言利用UDP实现群聊聊天室的示例代码
目录
- 1.UDP群聊的功能
- 2.写项目的流程
- 3.流程图
- 4.代码实现
- 4.1头文件
- 4.2函数
- 4.3服务器
- 4.4客户端
1.UDP群聊的功能 有新用户登录,其他在线的用户可以收到登录信息
有用户群聊,其他在线的用户可以收到群聊信息
有用户退出,其他在线的用户可以收到退出信息
服务器可以发送系统信息
2.写项目的流程 画流程图
根据流程图写框架
一个功能一个功能实现
3.流程图
文章图片
4.代码实现
4.1头文件
#ifndef __MYHEAD_H__#define __MYHEAD_H__ #include #define N 512//聊天操作用的结构体typedef struct _MSG{char ch; //用来'l'聊天,'q'退出,'登录d'char name[128]; //存名字char text[N]; //存聊天内容}msg_t; //用来保存每个用户信息的结构体typedef struct _Jilu{struct sockaddr_in addr; struct _Jilu *next; }jilu_t; int create_head(jilu_t **head); int input_addr(jilu_t *head,msg_t msg,int sockfd,struct sockaddr_in clientaddr,socklen_t clientaddr_len); int wx_addr(jilu_t *head,msg_t msg,int sockfd,struct sockaddr_in clientaddr,socklen_t clientaddr_len); int tuichu_addr(jilu_t *head,msg_t msg,int sockfd,struct sockaddr_in clientaddr,socklen_t clientaddr_len); #endif
【C语言利用UDP实现群聊聊天室的示例代码】
4.2函数
#include "myhead.h" //创建一个单链表头int create_head(jilu_t **head){if(head==NULL){printf("传送错误,请检查\n"); return -1; } (*head)=(jilu_t *)malloc(sizeof(jilu_t)); (*head)->next=NULL; return 0; } //记录登录的用户的信息int input_addr(jilu_t *head,msg_t msg,int sockfd,struct sockaddr_in clientaddr,socklen_t clientaddr_len){if(head==NULL){printf("传送错误,请检查\n"); return -1; } //将这个用户登录的信息发送给所有人snprintf(msg.text,sizeof(msg.text),"[%s]%s",msg.name,"登录了"); //这个用来记录头的地址jilu_t *jilu_head=head; while(jilu_head->next!=NULL){jilu_head=jilu_head->next; if(sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&jilu_head->addr,clientaddr_len)==-1){ERRLOG("将用户登录信息发给所有人失败"); }}//创建一个新的节点,并且把新的用户信息放入新得单列表jilu_t *temp=NULL; create_head(&temp); temp->addr=clientaddr; //用头插法将用户信息插入链表temp->next=head->next; head->next=temp; return 0; } int wx_addr(jilu_t *head,msg_t msg,int sockfd,struct sockaddr_in clientaddr,socklen_t clientaddr_len){if(head==NULL){printf("传送错误,请检查\n"); return -1; } //将接受到的消息发给除了自己以外的所有人jilu_t *jilu_head=head; while(jilu_head->next!=NULL){jilu_head=jilu_head->next; if(0!=memcmp(&(jilu_head->addr),&clientaddr,sizeof(clientaddr))){if(sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&jilu_head->addr,clientaddr_len)==-1){ERRLOG("将聊天内容发给所有人失败"); }}} return 0; }int tuichu_addr(jilu_t *head,msg_t msg,int sockfd,struct sockaddr_in clientaddr,socklen_t clientaddr_len){if(head==NULL){printf("传送错误,请检查\n"); return -1; } snprintf(msg.text,sizeof(msg.text),"%s%s",msg.name,"退出登录"); jilu_t *jilu_head=head; jilu_t *pdel=NULL; while(jilu_head->next!=NULL){if(0==memcmp(&(jilu_head->next->addr),&clientaddr,sizeof(clientaddr))){pdel=jilu_head->next; jilu_head->next=pdel->next; free(pdel); pdel=NULL; }else{jilu_head=jilu_head->next; if(sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&jilu_head->addr,clientaddr_len)==-1){ERRLOG("将这个退出的信息告诉所有人失败"); }}} return 0; }
4.3服务器
#include "myhead.h" int main(int argc, char const *argv[]){int sockfd=0; pid_t pid=0; msg_t msg; //用来进行各种操作msg_t faso; //用来发系统消息 if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1){ERRLOG("创建服务器套接字失败"); } //将网络信息结构体放入服务器中struct sockaddr_in serveraddr; memset(&serveraddr,0,sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(atoi(argv[2])); serveraddr.sin_addr.s_addr=inet_addr(argv[1]); socklen_t serveraddr_len=sizeof(serveraddr); //将套接字与网络信息结构体绑定if(bind(sockfd,(struct sockaddr*)&serveraddr,serveraddr_len)==-1){ERRLOG("将套接字与网络信息结构体绑定失败"); } //创建一个新的网络信息结构体来存客户端的信息struct sockaddr_in clientaddr; clientaddr.sin_family=AF_INET; socklen_t clientaddr_len=sizeof(clientaddr); //创建进程pid=fork(); if(pid==-1){ERRLOG("服务器创建进程失败"); }else if(pid==0){//创建一个单列表保存网络信息结构体jilu_t *head; create_head(&head); memset(&msg,0,sizeof(msg)); while(1){if(recvfrom(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&clientaddr,&clientaddr_len)==-1){ERRLOG("接受客户端传来的信息失败"); }switch(msg.ch){case 'd'://登录信息input_addr(head,msg,sockfd,clientaddr,clientaddr_len); //head->next=NULL; //这个用来测试用的break; case 'l'://聊天信息wx_addr(head,msg,sockfd,clientaddr,clientaddr_len); break; case 'q'://退出信息tuichu_addr(head,msg,sockfd,clientaddr,clientaddr_len); break; }}}else{while(1){//发系统消息memset(&faso,0,sizeof(faso)); fgets(faso.text,sizeof(faso.text),stdin); faso.text[strlen(faso.text)-1]='\0'; faso.ch='l'; sprintf(faso.name,"%s","系统消息"); if(sendto(sockfd,&faso,sizeof(faso),0,(struct sockaddr*)&serveraddr,serveraddr_len)==-1){ERRLOG("发送系统消息失败"); }}}return 0; }
4.4客户端
#include "myhead.h" int main(int argc, char const *argv[]){ //判断输入的对不对if(argc!=3){printf("输入格式错误,./a.out ip port\n"); exit(EXIT_SUCCESS); } int sockfd=0; pid_t pid=0; msg_t msg; //创建发送用户的信息 if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1){ERRLOG("创建客户端套接字失败"); } //将客户端网络信息结构体进行绑定struct sockaddr_in clientaddr; memset(&clientaddr,0,sizeof(clientaddr)); clientaddr.sin_family=AF_INET; clientaddr.sin_port=htons(atoi(argv[2])); clientaddr.sin_addr.s_addr=inet_addr(argv[1]); socklen_t clientaddr_len=sizeof(clientaddr); //输入用户的姓名进行登录操作msg.ch='d'; printf("请输入你用来登录的姓名"); fgets(msg.name,sizeof(msg.name),stdin); msg.name[strlen(msg.name)-1]='\0'; //给服务器发送用户已经登录上的操作if(sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&clientaddr,clientaddr_len)==-1){ERRLOG("客户端给服务器发送的登录信息失败"); }//创建进程,子进程用来接受,父进程用来发送pid=fork(); if(pid==-1){ERRLOG("客户端创建进程失败"); }else if(pid==0){//用来接受服务器发来的消息while(1){memset(&msg,0,sizeof(msg)); if(recvfrom(sockfd,&msg,sizeof(msg),0,NULL,NULL)==-1){ERRLOG("接受服务器发来的信息错误"); } printf("[%s]>>(%s)\n",msg.name,msg.text); }}else{//写入要判聊天的内容while(1){memset(msg.text,0,sizeof(msg.text)); fgets(msg.text,sizeof(msg.text),stdin); msg.text[strlen(msg.text)-1]='\0'; if(strncmp("quit",msg.text,5)==0){msg.ch='q'; }else{msg.ch='l'; }//将写好的内容发送给服务器if(sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&clientaddr,clientaddr_len)==-1){ERRLOG("将聊天内容发送给服务器失败"); } //当识别到停止的时候,关闭进程if(strncmp("quit",msg.text,5)==0){kill(pid,SIGKILL); close(sockfd); exit(EXIT_SUCCESS); }}} return 0; }
到此这篇关于C语言利用UDP实现群聊聊天室的示例代码的文章就介绍到这了,更多相关C语言 UDP聊天室内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- python证件照换底色_python利用opencv实现证件照换底
- python|利用Python制作证件照
- 机器学习系列文章|利用随机森林对特征重要性进行评估(公式原理)
- 编程语言|介绍 Docker 的多阶段构建功能
- Java基础-从0到1|【一起学Java-第八篇】Java语言类的特性详解
- YY|【C语言】通讯录《静态内存版本》
- 【C】系列|【C语言】内存函数
- C语言|【九日集训】《LeetCode刷题报告》题解内容 Ⅳ
- Antidote 10 for mac(多语言写作辅助软件)
- 编程语言|一起看 I/O | Android 更新一览