9.7(UDP局域网多客户端聊天室)

2024-09-08 03:52

本文主要是介绍9.7(UDP局域网多客户端聊天室),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

服务器端

#include<myhead.h>
#define SERIP "192.168.0.132"
#define SERPORT 8888
#define MAX 50
//定义用户结构体
typedef struct{struct sockaddr_in addr;int flag;
}User;User users[MAX];//用户列表void add_user(struct sockaddr_in *client){// 检查用户是否已经在列表中for (int i = 0; i < MAX; i++) {if (users[i].flag == 1 && memcmp(&users[i].addr, client, sizeof(struct sockaddr_in)) == 0) {// 用户已经在列表中return;}}for(int i=0;i<MAX;i++){if(users[i].flag==0){users[i].addr = *client;users[i].flag = 1;break;}}
}//向用户转发消息,排除发送者
void transform(char *buff,struct sockaddr_in *send,int oldfd){for(int i=0;i<MAX;i++){if(users[i].flag!=0){if(memcmp(&users[i].addr,send,sizeof(struct sockaddr_in))!=0){sendto(oldfd,buff,strlen(buff),0,(struct sockaddr *)&users[i].addr,sizeof(users[i].addr));}}}}int main (int argc, const char *argv[])
{//定义套接字int oldfd = socket(AF_INET,SOCK_DGRAM,0);if(oldfd==-1){perror("oldfd");return -1;}int kkk=2; if(setsockopt(oldfd,SOL_SOCKET,SO_BROADCAST,&kkk,sizeof(kkk))==-1){ perror("setsockopt"); return -1;} //绑定端口struct sockaddr_in server = {.sin_family = AF_INET,.sin_addr.s_addr = inet_addr(SERIP),.sin_port = htons(SERPORT)};int server_len = sizeof(server);if(bind(oldfd,(struct sockaddr *)&server,server_len)==-1){perror("bind");return -1;}printf("UDP聊天服务器启动,端口号为:%d\n",SERPORT);//IO多路复用struct pollfd fds[1];fds[0].fd = oldfd;fds[0].events = POLLIN;char buff[1024];struct sockaddr_in client;int client_len = sizeof(client);while(1){int poll_count = poll(fds,1,-1);if(fds[0].revents == POLLIN){memset(buff,0,sizeof(buff));int len = recvfrom(oldfd,buff,sizeof(buff),0,(struct sockaddr *)&client,&client_len);if(len == 0){perror("recvfrom");return -1;}buff[len] = '\0';printf("接收到来自%s:%d的消息%s\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port),buff);//添加用户到列表add_user(&client);//转发给其他用户transform(buff,&client,oldfd);}}close(oldfd);return 0;
}

客户端

#include<myhead.h>
#define SERIP "192.168.0.132"
#define SERPORT 8888
#define MAX 50int main (int argc, const char *argv[])
{//创建套接字int oldfd = socket(AF_INET,SOCK_DGRAM,0);if(oldfd==-1){perror("oldfd");return -1;}struct sockaddr_in server={.sin_family = AF_INET,.sin_port = htons(SERPORT),.sin_addr.s_addr = inet_addr(SERIP)};struct sockaddr_in client;int client_len = sizeof(client);int server_len = sizeof(server);printf("UDP客户端启动,连接到服务器%s:%d\n",inet_ntoa(server.sin_addr),ntohs(server.sin_port));char message[20] = "UDP客户端连接";sendto(oldfd,message,strlen(message),0,(struct sockaddr *)&server,server_len);struct pollfd fds[2];fds[0].fd = oldfd;fds[0].events = POLLIN;fds[1].fd = 0;fds[1].events = POLLIN;char buff[1024];while(1){int poll_count = poll(fds,2,5000);if(poll_count == -1){perror("poll_count");return -1;}if(poll_count == 0){continue;}if(fds[0].revents == POLLIN){memset(buff,0,sizeof(buff));int len = recvfrom(oldfd,buff,sizeof(buff),0,(struct sockaddr *)&server,&server_len);if(len<0){perror("recvfrom");continue;}buff[len]='\0';printf("服务器发来消息:%s\n",buff);}if(fds[1].revents==POLLIN){memset(buff,0,sizeof(buff));if(fgets(buff,sizeof(buff),stdin)!=NULL){buff[strlen(buff)-1]='\0';sendto(oldfd,buff,strlen(buff),0,(struct sockaddr *)&server,server_len);}}}close(oldfd);return 0;
}

效果:

image-20240907162254192

使用UDP以及I/O多路复用,实现了聊天内容的转发,以及在各个终端窗口的实时显示

不足

无法识别用户并再转发时加上用户的信息

这篇关于9.7(UDP局域网多客户端聊天室)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1147041

相关文章

Java Websocket实例【服务端与客户端实现全双工通讯】

Java Websocket实例【服务端与客户端实现全双工通讯】 现很多网站为了实现即时通讯,所用的技术都是轮询(polling)。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发 出HTTP request,然后由服务器返回最新的数据给客服端的浏览器。这种传统的HTTP request 的模式带来很明显的缺点 – 浏 览器需要不断的向服务器发出请求,然而HTTP

Redis 客户端Jedis使用---连接池

Jedis 是Redis 的Java客户端,通过一段时间的使用,jedis基本实现redis的所有功能,并且jedis在客户端实现redis数据分片功能,Redis本身是没有数据分布功能。 一、下载jedis 代码 jedis 代码地址:https://github.com/xetorthio/jedis 再次感受到开源的强大。呵呵,大家有时间可以看看源码。 二、项目中如何使用Jedi

Java Socket服务器端与客户端的编程步骤总结

一,InetAddress类: InetAddress类没有构造方法,所以不能直接new出一个对象; 可以通过InetAddress类的静态方法获得InetAddress的对象; InetAddress.getLocalHost(); InetAddress.getByName(""); 类主要方法: String - address.getHostName(); String - addre

C/C++ 网络聊天室在线聊天系统(整理重传)

知识点: TCP网络通信 服务端的流程: 1.创建socket套接字 2.给这个socket绑定一个端口号 3.给这个socket开启监听属性 4.等待客户端连接 5.开始通讯 6.关闭连接 解释: socket:类似于接口的东西,只有通过这个才能跟对应的电脑通信。 每一台电脑都有一个IP地址,一台电脑上有多个应用,每个应用都会有一个端口号。 socket一般分为两种类型,一种是通讯,一种是监听

VC环境下window网络程序:UDP Socket程序

最近在学Windows网络编程,正好在做UDPsocket的程序,贴上来: 服务器框架函数:              socket();    bind();    recfrom();  sendto();  closesocket(); 客户机框架函数:            socket();      recfrom();  sendto();  closesocket();

【知识分享】MQTT实战-使用mosquitto客户端连接emqx服务器

一、简介     MQTT(Message Queuing Telemetry Transport)是一种轻量级的、基于发布/订阅模式的通信协议,旨在实现物联网设备之间的低带宽、高延迟的通信。MQTT协议设计简洁,使用TCP/IP协议进行通信,适用于各种网络环境,尤其适合在有限的网络带宽和不稳定的网络连接条件下进行通信。     MQTT的工作原理是基于发布/订阅模式的消息传递,它包括两个主要

GitHub每日最火火火项目(9.7)

项目名称:polarsource / polar 项目介绍:polar 是一个开源的项目,它是 Lemon Squeezy 的替代方案,具有更优惠的价格。该项目旨在让开发者能够凭借自己的热情进行编码并获得报酬。通过使用 polar,开发者可以更轻松地实现自己的创意和项目,并从中获得收益。 项目地址:https://github.com/polarsource/polar项目名称:psf / bla

应用层简单实现udp / tcp网络通信

一、常见网络接口总结 1、创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器) int socket(int domain, int type, int protocol); domain:AF_INET:网络通信,AF_LOCAL:本地通信 type:UDP:SOCK_DGRAM,TCP:SOCK_STREAM protocol:协议编号一开始设0 返回值:文件描

AI周报(9.1-9.7)

AI应用-Tidal 引领海洋养殖革命 Tidal团队,一个源自Alphabet X的创新项目,今年七月顺利从X实验室毕业,成为一家独立的公司。Tidal正在通过人工智能技术改变海洋养殖,特别是鲑鱼养殖。Tidal的总部位于挪威特隆赫姆,他们结合了传感器、机器人、数据科学和人工智能技术,为鲑鱼养殖提供全面的解决方案。这个系统可以监控鱼类并提供产量估算,旨在在问题(如海虱)造成严重损害之前发现它们

【深入解析】AI工作流中的HTTP组件:客户端与服务端执行的区别

在当今快速发展的技术环境中,AI工作流的设计和实现变得愈发重要。尤其是在处理HTTP组件时,前端执行与后端执行之间的区别,往往会对系统的安全性和数据的准确性产生深远的影响。今天,我们就来深入探讨这一话题,揭示前端执行如何有效避免风控,以及它在获取本地数据方面的优势。 AI工作流+各种大模型=能用AI-工作流传送门:https://www.nyai.chat/chat?invite=nyai_