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

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

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

相关文章

【window】Windows11:该文件没有与之关联的应用来执行该操作

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff1a;人工智能 之前win10升级win11后&#xff0c;受不了桌面软件图标的的小箭头&#xff0c;所以弄掉了&#xff0c;但是随之而来产…

9个好习惯教会你设计商业模式的电商干货,真心分享丨运营逻辑

9个好习惯教会你设计商业模式的电商干货&#xff0c;真心分享丨运营逻辑 文丨微三云营销总监胡佳东&#xff0c;点击上方“关注”&#xff0c;为你分享市场商业模式电商干货。 - 最近&#xff0c;有很多新认识的朋友&#xff0c;都在询问我最近市场上&#xff0c;有什么好的…

定类变量的频率分析(SPSS

目录 1.导入数据&#xff1a;2.频率分析&#xff1a;3.结果分析4.表格导出为excel小结&#xff1a; 1.导入数据&#xff1a; 直接把表格拖入spss 然后点确定 下面会有变量视图&#xff0c;查看各个指标的类型和属性&#xff1a; 2.频率分析&#xff1a; 点击频率分析 选择…

json-server的基础使用

本篇文章与另一篇文章有关系axios的基本使用&#xff0c;大家可以看看这篇文章 json-server 是什么? 用来快速搭建模拟的 REST API 的工具包 可以30秒内快速为我们搭建一个假的基于 REST API的服务 我们要如何使用呢&#xff1f; 1.先安装 //全局安装 npm i -g json-server …

伪原创文章生成器软件免费使用的方法

写文章不仅消耗时间&#xff0c;而且还容易出现写不出内容的问题&#xff0c;随着技术的发展&#xff0c;越来越多的人开始不再亲历亲为的去写文章了&#xff0c;而是用起了伪原创文章生成器软件&#xff0c;对于还不了解自动生成文章软件的人&#xff0c;可不要小瞧这个它了&a…

JOSEF约瑟 零序电流继电器 JL-8D/2X122A4(S) 0-30AAC 220VDC

系列型号 JL-8D/3X1定时限电流继电器&#xff1b;JL-8D/3X111A2定时限电流继电器&#xff1b; JL-8D/3X121A2定时限电流继电器&#xff1b;JL-8D/3X211A2定时限电流继电器&#xff1b; JL-8D/3X221A2定时限电流继电器&#xff1b;JL-8D/3X2定时限电流继电器&#xff1b; JL-8D/…

[小程序]Http网络请求

一、数据请求限制 出于安全性(bushi)考虑&#xff0c;小程序请求的数据接口必须具备以下两个条件&#xff1a; ①只能请求Https类型 ②必须将接口域名添加到信任列表中 1.配置request合法域名 配置步骤如下&#xff1a;小程序管理后台->开发->开发设置->服务器域名-&g…

幻兽帕鲁专用服务器

随着幻兽帕鲁这款游戏的热度持续升温&#xff0c;我们遍寻全网&#xff0c;带给各位玩家一个全新的、高品质的游戏体验——莱卡云服务器。有幻兽帕鲁的热衷者们无需再为了服务器的选取困扰&#xff0c;因为我们可以肯定地说&#xff1a;选择莱卡云&#xff0c;你不会失望。 首先…

java SSM政府采购管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM政府采购管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代 码和数据库&#xff0c;系统主要采…

飞书+ChatGPT+cpolar搭建企业智能AI助手并实现无公网ip远程访问

文章目录 推荐 前言环境列表1.飞书设置2.克隆feishu-chatgpt项目3.配置config.yaml文件4.运行feishu-chatgpt项目5.安装cpolar内网穿透6.固定公网地址7.机器人权限配置8.创建版本9.创建测试企业10. 机器人测试 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂…

C语言第五弹---分支语句(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 分支语句 1、if语句1.1、if1.2、 else1.3、 分支中包含多条语句1.4、嵌套if1.5、 悬空else问题 2、关系操作符3、 条件操作符总结 C语言是结构化的程序设计语言&…

第04章_IDEA的安装与使用(下)(IDEA断点调试,IDEA常用插件)

文章目录 第04章_IDEA的安装与使用&#xff08;下&#xff09;8. 快捷键的使用8.1 常用快捷键8.2 查看快捷键1、已知快捷键操作名&#xff0c;未知快捷键2、已知快捷键&#xff0c;不知道对应的操作名 8.3 自定义快捷键8.4 使用其它平台快捷键 9. IDEA断点调试(Debug)9.1 为什么…

一零七七、将Hexo cl Hexo g Hexo s通过systemctl命令管理

背景&#xff1a; 服务器需要执行hexo s来运行项目&#xff0c;但这个命令是基于前台的&#xff0c;故想直接嫁接在systemctl命令基础上来控制环境&#xff1a; Centos 8 前置环境就不说了,Hexo安装好&#xff0c;起码装完自己得先看hexo命令生效没&#xff0c;前置环境做好后…

Leetcode刷题笔记题解(C++):LCR 102. 目标和

思路&#xff1a;利用回溯去遍历&#xff0c;回溯结束条件为遍历到最后一个数字&#xff0c;如果符合target则目标数1 class Solution { public://记录合为结果的数量int count 0;int findTargetSumWays(vector<int>& nums, int target) {//利用回溯来寻找backtrac…

《WebKit 技术内幕》之九(2): JavaScript引擎

2 V8引擎 2.1 基础 V8是一个开源项目&#xff0c;也是一个JavaScript引擎的实现。它最开始是由一些语言方面的专家设计出来的&#xff0c;后被Google收购&#xff0c;成为了JavaScript引擎和众多相关技术的引领者。其目的很简单&#xff0c;就是为了提高性能。因为在当时之前…

#vue3 实现前端下载excel文件模板功能

一、需求&#xff1a; 前端无需通过后端接口&#xff0c;即可实现模板下载功能。 通过构造一个 JSON 对象&#xff0c;使用前端常用的第三方库 xlsx&#xff0c;可以直接将该 JSON 对象转换成 Excel 文件&#xff0c;让用户下载模板 二、效果&#xff1a; 三、源码如下&…

MES智能制造系统,定制智造工厂的“大脑”,提升生产力智慧之选

制造执行系统&#xff08;MES&#xff09;是专为制造企业设计的执行管理软件&#xff0c;用于管理整个工厂的生产过程。随着智能制造的推动&#xff0c;信息技术水平的提升对于实现智能工厂至关重要在数字化技术不断进步和发展的背景下&#xff0c;MES系统作为面向制造企业车间…

【JavaEE进阶】 Spring Boot⽇志

文章目录 &#x1f38b;关于日志&#x1f6a9;为什么要学习⽇志&#x1f6a9;⽇志的⽤途&#x1f6a9;日志的简单使用 &#x1f384;打印⽇志&#x1f6a9;程序中得到⽇志对象&#x1f6a9;使⽤⽇志对象打印⽇志 &#x1f38d;⽇志格式的说明&#x1f6a9;⽇志级别的作用&#…

实时asr新服务串讲

1.背景及现状 工程方面目前语音相关服务存在大量重复代码&#xff0c;逻辑复杂&#xff0c;文档缺失&#xff0c;并且某些细节设计不合理。基于目前现状&#xff0c;代码业务与功能耦合严重&#xff0c;迭代困难&#xff0c;将来增加新的能力也需要改动音频数据相关代码&#x…

Allegro如何导入芯片的Pin Delay?

Allegro在做等长时,需要导入芯片的Pin Delay才能做真正的等长。因为有些芯片内部的引脚本身就是不等长的,例如海思的部分芯片。 那么如何导入芯片的Pin Delay呢? 1、打开约束管理器,点击Properties(属性)→Component(器件)→Pin Properties→General。 在右栏找到芯片U1,…