UDP实现群聊通信

服务器端

#include <myhead.h>
#define UDPIP "192.168.115.92"
#define UDPPORT 6666
//存储客户信息的链表结构体
typedef struct Node
{char name[20];struct sockaddr_in cin;struct Node *next;
}*linklist;
//数据结构体
struct data_cli
{char type;char name[20];char text[128];
};
//创建节点
linklist create_space()
{linklist s=(linklist)malloc(sizeof(struct Node));if(NULL==s)return NULL;bzero(s->name,sizeof(s->name));s->next=NULL;return s;
}
//末尾插入信息
linklist Insert_end(linklist head,struct sockaddr_in cin,char name[20])
{//创建节点linklist s=create_space();s->cin=cin;strcpy(s->name,name);//判断之前是否有节点if(NULL==head){head=s;return head;}linklist p=head;while((p->next)!=NULL){p=p->next;}p->next=s;//未尾插入return head;}
//删除退出客户
linklist Delete_by_ele(linklist head,in_port_t cin_port)
{if(NULL==head)return NULL;linklist p=head;if(NULL==head->next){free(head);return NULL;}while(p!=NULL){if(ntohs(cin_port)==ntohs(p->cin.sin_port)){linklist del=p->next;//多个字节p->cin=del->cin;strcpy(p->name,del->name);p->next=del->next;free(del);del=NULL;return head;}if(p->next->next==NULL){linklist q=p->next;free(q);p->next=NULL;return head;}p=p->next;}return head;}int main(int argc, const char *argv[])
{//创建头指针linklist head=NULL;//1.创建套接字文件int tfd;if((tfd=socket(AF_INET,SOCK_DGRAM,0))==-1){perror("socket");return -1;}//2.绑定IP和端口struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(UDPPORT);sin.sin_addr.s_addr=inet_addr(UDPIP);if(bind(tfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("bind");return -1;}printf("bind success\n");//io多路复用信息fd_set readfds,tempfds;FD_ZERO(&readfds);FD_SET(0,&readfds);FD_SET(tfd,&readfds);int maxfd=tfd;//3.收发信息struct sockaddr_in cin1;cin1.sin_family=AF_INET;socklen_t len=sizeof(cin1);char buf[128]="";int res;struct data_cli cli_data;while(1){tempfds=readfds;//等待唤醒条件res=select(maxfd+1,&tempfds,NULL,NULL,NULL);if(res<0){perror("select");return -1;}else if(res==0){printf("超时\n");return -1;}if(FD_ISSET(0,&tempfds)){//系统向所有客户端发消息bzero(&cli_data,sizeof(struct data_cli));strcpy(cli_data.name,"系统消息:");fgets(cli_data.text,sizeof(cli_data.text),stdin);cli_data.text[strlen(cli_data.text)-1]=0;linklist p=head;while(p!=NULL){sendto(tfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&p->cin,len);p=p->next;}printf("系统发送消息成功\n");}if(FD_ISSET(tfd,&tempfds)){bzero(&cli_data,sizeof(struct data_cli));recvfrom(tfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&cin1,&len);switch(cli_data.type){case 'D':{strcpy(cli_data.text,"上线了");linklist p=head;while(p!=NULL){sendto(tfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&p->cin,len);p=p->next;}head=Insert_end(head,cin1,cli_data.name);printf("[%s:%d]:%s\n",inet_ntoa(cin1.sin_addr),ntohs(cin1.sin_port),"登录成功");}break;case 'S':{linklist p=head;while(p!=NULL){if(p->cin.sin_port==cin1.sin_port){if(p->next!=NULL){p=p->next;}else{break;}}sendto(tfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&p->cin,len);p=p->next;}printf("[%s:%d]:%s\n",inet_ntoa(cin1.sin_addr),ntohs(cin1.sin_port),"客户端发送消息");}break;case 'Q':{head=Delete_by_ele(head,cin1.sin_port);strcpy(cli_data.text,"下线了");linklist p=head;while(p!=NULL){sendto(tfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&p->cin,len);p=p->next;}printf("[%s:%d]:%s\n",inet_ntoa(cin1.sin_addr),ntohs(cin1.sin_port),"客户端退出");}break;}}}//4.关闭文件close(tfd);return 0;
}

客户端
 

#include <myhead.h>
#define IP "192.168.115.92"
#define PORT 6666
//定义信息结构体
struct data_cli
{char type;char name[20];char text[128];
};
int main(int argc, const char *argv[])
{//1.创建套接字int cfd;cfd=socket(AF_INET,SOCK_DGRAM,0);if(cfd==-1){perror("socket");return -1;}//io多路复用信息fd_set readfds,tempfds;FD_ZERO(&readfds);FD_SET(0,&readfds);FD_SET(cfd,&readfds);int maxfd=cfd;//3.收发数据struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(PORT);sin.sin_addr.s_addr=inet_addr(IP);socklen_t len=sizeof(struct sockaddr_in);//创建账户struct data_cli cli_data;bzero(&cli_data,sizeof(struct data_cli));printf("请登录用户:");cli_data.type='D';fgets(cli_data.name,sizeof(cli_data.name),stdin);cli_data.name[strlen(cli_data.name)-1]=0;char myname[20]="";strcpy(myname,cli_data.name);sendto(cfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&sin,len);char buf[256]="";int res;while(1){tempfds=readfds;//等待唤醒条件res=select(maxfd+1,&tempfds,NULL,NULL,NULL);if(res<0){perror("select");return -1;}else if(res==0){printf("超时\n");return -1;}if(FD_ISSET(0,&tempfds)){bzero(&cli_data,sizeof(struct data_cli));cli_data.type='S';strcpy(cli_data.name,myname);fgets(cli_data.text,sizeof(cli_data.text),stdin);cli_data.text[strlen(cli_data.text)-1]='\0';if(strcmp("quit",cli_data.text)==0){cli_data.type='Q';sendto(cfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&sin,len);break;}sendto(cfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&sin,len);}if(FD_ISSET(cfd,&tempfds)){bzero(buf,sizeof(buf));bzero(&cli_data,sizeof(struct data_cli));recvfrom(cfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&sin,&len);sprintf(buf,"[%s]:%s",cli_data.name,cli_data.text);printf("%s\n",buf);}}//4.关闭close(cfd);return 0;
}

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

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

相关文章

分类预测 | Matlab实现NGO-KELM北方苍鹰算法优化核极限学习机分类预测

分类预测 | Matlab实现NGO-KELM北方苍鹰算法优化核极限学习机分类预测 目录 分类预测 | Matlab实现NGO-KELM北方苍鹰算法优化核极限学习机分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现NGO-KELM北方苍鹰算法优化核极限学习机分类预测&#xff08;完…

只会在终端使用Python运行代码?这些高级用法了解了解

大部分同学在终端使用Python可能只是简单的执行代码&#xff0c;但其实结合一些Python内置模块或第三方库可以实现更高级且便捷的用法&#xff0c;一起看看吧 插播&#xff0c;更多文字总结指南实用工具科技前沿动态第一时间更新在公粽号【啥都会一点的研究生】 代码Benchmar…

【代码】基于卷积神经网络(CNN)-支持向量机(SVM)的分类预测算法

程序名称&#xff1a;基于卷积神经网络&#xff08;CNN&#xff09;-支持向量机&#xff08;SVM&#xff09;的分类预测算法 实现平台&#xff1a;matlab 代码简介&#xff1a;CNN-SVM是一种常用的图像分类方法&#xff0c;结合了卷积神经网络&#xff08;CNN&#xff09;和支…

绝地求生:成长型皮肤异色定价是否有些夸张?

大家好&#xff0c;我闲游盒小盒子&#xff01; 自从26.2更新上架回归的黑市中四款成长型皮肤以后&#xff0c;能看到社区里很多玩家都分享抽中了自己心仪的成长型皮肤。 但是对于异色很少有人去实装&#xff0c;大多数玩家都是选择去分解异色换取五张图纸然后追求升级原皮等级…

【古月居《ros入门21讲》学习笔记】15_ROS中的坐标系管理系统

目录 说明&#xff1a; 1. 机器人中的坐标变换 tf功能包能干什么&#xff1f; tf坐标变换如何实现 2. 小海龟跟随实验 安装 ros-melodic-turtle-tf 实验命令 运行效果 说明&#xff1a; 1. 本系列学习笔记基于B站&#xff1a;古月居《ROS入门21讲》课程&#xff0c;且使…

怎么更新BI报表数据?问我就对了

BI大数据分析工具上有大量的BI报表模板&#xff0c;这些模板都是一个个完整的BI报表&#xff0c;只需将数据源更换&#xff0c;立即就能用来分析我们自己的数据。那&#xff0c;BI报表的数据怎么更新&#xff1f;接下来就来说说这事。 目的&#xff1a;更新BI报表数据 工具&a…

Flask教程入门

1.学习Flask之前&#xff0c;首先需要对URL进行一定的了解。 URL的一些知识&#xff1a; 1.URL只能包含ASCII码里面一些可显示的字符&#xff0c;如A-Z&#xff0c;a-z&#xff0c;0-9&#xff0c;&&#xff0c;#&#xff0c;%&#xff0c;&#xff1f;&#xff0c;/等字符…

vue项目中使用jsonp跨域请求百度联想接口

一. 内容简介 vue项目中使用jsonp跨域请求百度联想接口 二. 软件环境 2.1 Visual Studio Code 1.75.0 2.2 chrome浏览器 2.3 node v18.14.0 三.主要流程 3.1 代码 核心代码 // 这个是请求函数doLeno() {// 挂载回调函数&#xff0c;不挂载&#xff0c;会报不存在window…

Slf4j使用Logback时,Logback如何初始化

前言 Slf4j SLF4J&#xff0c;全称 Simple Logging Facade for Java&#xff0c;是一个用于Java编程语言的日志系统抽象层。它为多种现有日志框架&#xff08;例如Log4j、java.util.logging等&#xff09;提供了统一的接口, 但自身并不实现日志功能。 SLF4J 允许用户在部署时…

神经网络核心组件和流程梳理

文章目录 神经网络核心组件和流程梳理组件流程 神经网络核心组件和流程梳理 组件 层&#xff1a;神经网络的基本结构&#xff0c;将输入张量转换为输出张量。模型&#xff1a;由层构成的网络。损失函数&#xff1a;参数学习的目标函数&#xff0c;通过最小化损失函数来学习各…

大坝安全监测的内容及作用

大坝安全监测是指对大坝水雨情沉降、倾斜、渗压以及大坝形状特征有效地进行监测&#xff0c;及时发现潜在的安全隐患和异常情况&#xff0c;以便大坝管理人员能够做出科学决策&#xff0c;以确保大坝安全稳定运行。 大坝安全监测的主要内容 1.表面位移监测&#xff1a;监测大坝…

【vue】v-model在表单元素上的应用

表单元素&#xff1a; https://blog.csdn.net/m0_67930426/article/details/134655644 使用模板 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head><body>&l…