UDP网络聊天室
1.服务器端#include udp.h int main(int argc, const char *argv[]) { printf(******************************************************\n); printf(******************************************************\n); printf(************************聊天室************************\n); printf(******************************************************\n); printf(******************************************************\n); signal(SIGCHLD,handler); node_p Hcreate_H(); int sfdsocket(AF_INET,SOCK_DGRAM,0); if(sfd-1) { perror(scoket error); return -1; } // printf(socket success sfd%d\n,sfd); int reuse 1; if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, reuse, sizeof(reuse))-1) { perror(setsockopt error); return -1; } // printf(端口号快速重用成功\n); struct sockaddr_in sin; sin.sin_familyAF_INET; sin.sin_porthtons(SER_PORT); sin.sin_addr.s_addrinet_addr(SER_IP); if(bind(sfd,(struct sockaddr*)sin,sizeof(sin))-1) { perror(bind error); return -1; } // printf(bind success\n); struct sockaddr_in cin; socklen_t socklensizeof(cin); Msg recvmsg; char rbuf[128]; pid_t pid; pidfork(); if(pid0) { while(1) { memset(recvmsg,0,sizeof(recvmsg)); if(recvfrom(sfd,recvmsg,sizeof(recvmsg),0,\ (struct sockaddr*)cin,socklen)-1) { perror(recvfrom error); return -1; } switch(recvmsg.type) { case L: //向连接客户端所有用户遍历发送xx登录 //并且将用户信息添加进链表 //用户自己不需要接收自己登录信息,所以后插入 inset_usrmsg(sfd,H,recvmsg,cin); break; case C: //聊天信息将发送到除去发送用户的每一个人 sendto_chatmsg(sfd,H,recvmsg,cin); break; case Q: //用户退出信息 //遍历链表如果不是退出用户信息将其他用户退出信息发送 //若果是此用户将其用户信息从链表中删除 sendto_quitmsg(sfd,H,recvmsg,cin); break; } } exit(EXIT_SUCCESS); } else if(pid0) { //系统发送消息到所有客户端为C类消息 recvmsg.typeC; strcpy(recvmsg.usrname,系统消息); while(1) { //将信息发送到子进程由子进程转发 fgets(recvmsg.msgtext,sizeof(recvmsg.msgtext),stdin); recvmsg.msgtext[strlen(recvmsg.msgtext)-1]0; if(sendto(sfd,recvmsg,sizeof(recvmsg),0,(struct sockaddr*)sin,sizeof(sin))-1) { perror(sendto error); return -1; } // printf(ok\n); } } close(sfd); return 0; } //创建头结点 node_p create_H() { node_p H(node_p)malloc(sizeof(node)); if(NULLH) { printf(申请空间失败\n); return NULL; } H-nextNULL; return H; } //申请新节点保存客户端信息数据 node_p create_new_point(node_p H,Msg recvmsg,struct sockaddr_in cin) { node_p new(node_p)malloc(sizeof(node)); if(NULLnew) { printf(申请空间失败\n); return NULL; } //将接收到的信息结构体中的信息保存到新节点中 strcpy(new-name,recvmsg.usrname); new-cincin; new-nextH-next; H-nextnew; printf(%s:%s\n,recvmsg.usrname,recvmsg.msgtext); return new; } int inset_usrmsg(int sfd,node_p H,Msg recvmsg,struct sockaddr_in cin) { if(NULLH) { printf(入参为空\n); return -1; } //直接将 xx登录 消息发送给当前聊天室内成员 node_p pH; while(p-next!NULL) { pp-next; if(sendto(sfd,recvmsg,sizeof(recvmsg),0,(struct sockaddr*)(p-cin),sizeof(p-cin))-1) { perror(error sendto); return -1; } } node_p newcreate_new_point(H,recvmsg,cin); return 0; } int sendto_chatmsg(int sfd,node_p H,Msg recvmsg,struct sockaddr_in cin) { if(NULLH) { printf(入参为空\n); return -1; } node_p pH; //遍历整条链表如果不是发送节点用户,服务器将消息转发 while(p-next!NULL) { pp-next; if(memcmp((p-cin),cin,sizeof(cin))) { if(sendto(sfd,recvmsg,sizeof(recvmsg),0,(struct sockaddr*)(p-cin),sizeof(p-cin))-1) { perror(send sfd); return -1; } } } printf(----------------%schat---------------\n,recvmsg.usrname); return 0; } int sendto_quitmsg(int sfd,node_p H,Msg recvmsg,struct sockaddr_in cin) { if(NULLH) { printf(入参为空\n); return -1; } node_p pH; while(p-next!NULL) { //遍历节点先找到退出登录的用户节点的前一个节点 //其他节点直接转发用户突出登录信息 if(memcmp((p-next-cin),cin,sizeof(cin))) { pp-next; if(sendto(sfd,recvmsg,sizeof(recvmsg),0,(struct sockaddr*)(p-cin),sizeof(p-cin))-1) { perror(error sfd); return -1; } } else { node_p delep-next; p-nextdele-next; free(dele); dele-nextNULL; } } } void handler(int signum) { if(signumSIGCHLD) { while(waitpid(-1,NULL,WNOHANG)0); } }2.客户端#include udp.h int main(int argc, const char *argv[]) { if(argc!3) { printf(请绑定IP地址与端口号\n); return -1; } printf(***************Jion:加入聊天室*************\n); printf(***************Quit:我再想一想*************\n); char chat[32]; scanf(%s,chat); while(getchar()!10); if(chat[0]j||chat[0]J) { printf(****WELCOME****\n); } else { return 0; } int cfdsocket(AF_INET,SOCK_DGRAM,0); if(cfd-1) { perror(socket error); return -1; } // printf(socket success cfd%d\n,cfd); struct sockaddr_in cin; cin.sin_familyAF_INET; cin.sin_porthtons(atoi(argv[2])); cin.sin_addr.s_addrinet_addr(argv[1]); if(bind(cfd,(struct sockaddr*)cin,sizeof(cin))-1) { perror(bind error); return -1; } // printf(bind success\n); struct sockaddr_in sin; sin.sin_familyAF_INET; sin.sin_porthtons(SER_PORT); sin.sin_addr.s_addrinet_addr(SER_IP); //客户端运行用户登录 Msg msgsend; bzero(msgsend,sizeof(msgsend)); //printf();//提示是否登录 printf(请输入用户名:); scanf(%s,msgsend.usrname); while(getchar()!10); char name[32]; bzero(name,32); strcpy(name,msgsend.usrname); printf(登陆成功\n); printf(输入任意键清屏\n); getchar(); system(clear); strcat(msgsend.msgtext,已登陆); msgsend.typeL;//登录消息消息类型为L sendto(cfd,msgsend,sizeof(msgsend),0,\ (struct sockaddr*)sin,sizeof(sin));//向客户端发送登录信息 struct pollfd pfds[2]; pfds[0].fd0; pfds[0].eventsPOLLIN; pfds[1].fdcfd; pfds[1].eventsPOLLIN; char wbuf[128]; while(1) { int respoll(pfds,2,-1); if(res0) { printf(time out\n); return -1; } else if(res-1) { perror(poll error); return -1; } if(pfds[0].reventsPOLLIN) { //群聊信息 bzero(msgsend,sizeof(msgsend)); strcpy(msgsend.usrname,name); fgets(msgsend.msgtext,sizeof(msgsend.msgtext),stdin); msgsend.msgtext[strlen(msgsend.msgtext)-1]0; if(strcmp(msgsend.msgtext,quit)) { msgsend.typeC; sendto(cfd,msgsend,sizeof(msgsend),0,\ (struct sockaddr*)sin,sizeof(sin)); } else if(strcmp(msgsend.msgtext,quit)0) { msgsend.typeQ; strcpy(msgsend.msgtext,退出群聊); if(sendto(cfd,msgsend,sizeof(msgsend),0,\ (struct sockaddr*)sin,sizeof(sin))-1) { perror(sendto error); return -1; } close(cfd); printf(您已经退出群聊\n); break; } } else if(pfds[1].reventsPOLLIN) { //接受服务器发送的消息 //包括服务器转发的其他用户消息与系统消息 bzero(msgsend,sizeof(msgsend)); if(recvfrom(cfd,msgsend,sizeof(msgsend),0,NULL,NULL)-1) { perror(recvfrom error); return -1; } printf(%s:%s\n,msgsend.usrname,msgsend.msgtext); } } return 0; }3.头文件#ifndef __UDP_H__ #define __UDP_H__ #include myhead.h #define SER_IP 192.168.125.20 #define SER_PORT 7171 typedef struct node { char name[32]; struct sockaddr_in cin; struct node* next; }node,*node_p; typedef struct msgTyp { char type;//L.C.Q char usrname[20]; char msgtext[1024]; }Msg; node_p create_H(); node_p create_new_point(node_p H,Msg recvmsg,struct sockaddr_in cin); int inset_usrmsg(int sfd,node_p H,Msg recvmsg,struct sockaddr_in cin); int sendto_chatmsg(int sfd,node_p H,Msg recvmsg,struct sockaddr_in cin); int sendto_quitmsg(int sfd,node_p H,Msg recvmsg,struct sockaddr_in cin); void handler(int signum); #endif

相关新闻

【实战】LS-DYNA授权管理优化实战:从成本中心到价值引擎

【实战】LS-DYNA授权管理优化实战:从成本中心到价值引擎

从成本中心到价值引擎:LS-DYNA 授权管理优化解决方案深度解析一、行业背景与挑战:仿真驱动设计的基石与隐痛在当今汽车行业,从车身结构设计到碰撞安全仿真,从 NVH(噪声、振动与声振粗糙度)分析到热管理优化…

2026/7/10 13:57:32阅读更多 →
基于ADS127L11与PIC18F66K40的高精度数据采集系统设计

基于ADS127L11与PIC18F66K40的高精度数据采集系统设计

1. 项目概述:高精度模拟信号采集系统设计在工业测量、医疗设备和科学仪器等领域,我们经常需要将微弱的模拟信号转换为高精度的数字数据。这次要分享的是一个基于ADS127L11 Δ-Σ ADC和PIC18F66K40微控制器的信号采集系统设计方案,它能实现24位…

2026/7/10 13:52:22阅读更多 →
LinkSwift:本地化网盘直链解析工具的技术深度解析

LinkSwift:本地化网盘直链解析工具的技术深度解析

LinkSwift:本地化网盘直链解析工具的技术深度解析 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘…

2026/7/10 13:52:22阅读更多 →
3小时深度体验:如何构建你的专属AI对话系统?

3小时深度体验:如何构建你的专属AI对话系统?

3小时深度体验:如何构建你的专属AI对话系统? 【免费下载链接】LibreChat Enhanced ChatGPT Clone: Features Agents, MCP, Skills, DeepSeek, Anthropic, AWS, OpenAI, Responses API, Azure, Groq, o1, GPT-5, Mistral, OpenRouter, Vertex AI, Gemini,…

2026/7/10 15:02:41阅读更多 →
WechatDecrypt:快速解锁你的微信聊天记录,重新掌控数字记忆

WechatDecrypt:快速解锁你的微信聊天记录,重新掌控数字记忆

WechatDecrypt:快速解锁你的微信聊天记录,重新掌控数字记忆 【免费下载链接】WechatDecrypt 微信消息解密工具 项目地址: https://gitcode.com/gh_mirrors/we/WechatDecrypt 你是否曾经因为微信聊天记录无法备份而烦恼?那些珍贵的对话…

2026/7/10 15:02:41阅读更多 →
AI写歌用什么App好?2026国产商用软件推荐测评

AI写歌用什么App好?2026国产商用软件推荐测评

很多人刷到短视频里的原创BGM、朋友发的AI写的歌,都会好奇:现在AI写歌到底用什么App好?尤其是普通用户,既想操作简单、不用懂乐理,又想歌的质量过关、最好能商用发平台,还要合规安全不踩坑。 我们花了一周时…

2026/7/10 15:02:41阅读更多 →
RIME for macOS 深度技术解析:从架构设计到高级定制化实践

RIME for macOS 深度技术解析:从架构设计到高级定制化实践

RIME for macOS 深度技术解析:从架构设计到高级定制化实践 【免费下载链接】squirrel 【鼠鬚管】Rime for macOS 项目地址: https://gitcode.com/gh_mirrors/squ/squirrel 鼠鬚管(Squirrel)作为基于RIME输入法引擎的macOS前端实现&…

2026/7/10 15:02:41阅读更多 →
OpenCore Legacy Patcher终极教程:让旧Mac焕发新生的完整指南

OpenCore Legacy Patcher终极教程:让旧Mac焕发新生的完整指南

OpenCore Legacy Patcher终极教程:让旧Mac焕发新生的完整指南 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 还在为你的老Mac无法升级到最新macO…

2026/7/10 15:02:41阅读更多 →
2026年许可采购趋势:企业应该如何提前布局?

2026年许可采购趋势:企业应该如何提前布局?

如果你还在用三年前的采购逻辑来决策今年的软件预算,那你已经落后了。2026年的软件许可市场正在经历一场深刻的重构。license management市场预计从2025年的14.3亿美元增长至2026年的15.9亿美元,年复合增长率达到11.04%。软件资产管理市场更猛&#xff0…

2026/7/10 14:57:41阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述:从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目,叫 skills4/skills ,它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景:一个旨在展示或教授某种技能的仓库,本身却成了安…

2026/7/10 12:10:00阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示:因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战:从“黑箱预测”到“可信推理”2026年6月,第7届机器学习与趋势国际会议(MLT 2026)将在悉尼召开。会议议程中,“因果与可解释机器学习…

2026/7/10 12:29:21阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时,通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中,是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/10 4:59:05阅读更多 →
浏览器缓存行为深度解析:Chrome/Firefox/Safari 对 304 响应的 5 种触发场景对比

浏览器缓存行为深度解析:Chrome/Firefox/Safari 对 304 响应的 5 种触发场景对比

浏览器缓存行为深度解析:Chrome/Firefox/Safari 对 304 响应的 5 种触发场景对比当你在浏览器地址栏敲入一个网址时,背后可能隐藏着一场关于"要不要重新下载资源"的精密博弈。这场博弈的裁判是HTTP缓存机制,而304状态码则是这场博弈…

2026/7/10 0:00:01阅读更多 →
RoboWits:面向创造性问题求解的双臂机器人认知推理基准

RoboWits:面向创造性问题求解的双臂机器人认知推理基准

1. 项目概述:这不是又一个机器人抓取数据集,而是一次对“思考力”的压力测试 RoboWits——这个名字里藏着两个关键信号:“Robo”直指物理世界中的具身智能体,“Wits”则毫不掩饰地指向人类最核心的认知能力:机敏、判断…

2026/7/10 0:00:01阅读更多 →
5分钟完全指南:如何使用TegraRcmGUI图形化工具解锁Switch无限可能

5分钟完全指南:如何使用TegraRcmGUI图形化工具解锁Switch无限可能

5分钟完全指南:如何使用TegraRcmGUI图形化工具解锁Switch无限可能 【免费下载链接】TegraRcmGUI C GUI for TegraRcmSmash (Fuse Gele exploit for Nintendo Switch) 项目地址: https://gitcode.com/gh_mirrors/te/TegraRcmGUI TegraRcmGUI是一款专为Windows…

2026/7/10 0:00:01阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/10 13:39:09阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/9 15:50:44阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/9 14:14:17阅读更多 →