UDP网络聊天室(更)

服务器端

#include <header.h>
typedef struct node
{
	char name[20];
	struct sockaddr_in cli_addr;
	struct node *next;
}node,*node_p;
typedef struct msg
{
	char type;
	char name[20];
	char text[128];
}msg;
node_p create_link()
{
	node_p H=(node_p)malloc(sizeof(node));
	if(H==NULL)
	{
		printf("apply fail\n");
		return NULL;
	}
	H->next=NULL;
	return H;
}
node_p create_node(char *name,struct sockaddr_in cli_addr)
{
	node_p new=(node_p)malloc(sizeof(node));
	if(new==NULL)
	{
		printf("apply fail\n");
		return NULL;
	}
	strcpy(new->name,name);
	new->cli_addr=cli_addr;
	new->next=NULL;
	return new;
}
void insert(node_p H,char *name,struct sockaddr_in cli_addr)
{
	if(H==NULL)
	{
		printf("apply fail\n");
		return;
	}
	node_p new=create_node(name,cli_addr);
	new->next=H->next;
	H->next=new;
}
void delete(node_p H,char* name)
{
	if(H==NULL)
	{
		printf("apply fail\n");
		return;
	}
	node_p p=H->next;
	while(p!=NULL&&strcmp(p->next->name,name)!=0)
	{
		p=p->next;
	}
	node_p p1=p->next;
	p->next=p->next->next;
	free(p1);
}
int main(int argc, const char *argv[])
{
	if(argc!=3)
	{
		printf("请依次输入正确的ip地址和端口号!\n");
		return 1;
	}
	const char *SER_IP=argv[1];
	int SER_PORT=atoi(argv[2]);

	int sfd=socket(AF_INET,SOCK_DGRAM,0);               
	if(sfd==-1)
	{
		perror("socket");
		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");
		return 1;
	}
	struct sockaddr_in cin;
	socklen_t addrlen=sizeof(cin);
	char wbuf[128]={0};
	struct pollfd pfd[2];
	pfd[0].fd=sfd;
	pfd[1].fd=0;
	pfd[0].events=POLLIN;
	pfd[1].events=POLLIN;
	node_p H=create_link();
	msg msg;
	printf("等待用户加入....\n");
	while(1)
	{
		int res=poll(pfd,2,-1);
		if(res==-1)
		{
			perror("poll");
			return 1;
		}
		else if(res==0)
		{
			printf("time out\n");
			return 1;
		}
		if(pfd[0].revents==POLLIN)
		{
			memset(&msg,0,sizeof(msg));
			recvfrom(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&cin,&addrlen);
			if(msg.type=='n')
			{
				node_p p=H->next;
				insert(H,msg.name,cin);
				printf("*********\033[1;35m[%s\033[0m:\033[1;32m%d] \033[33m %s\033[0m\033[1;36m 已进入聊天室\033[0m*********** \n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),msg.name);
				while(p!=NULL)
				{
					sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&p->cli_addr,sizeof(p->cli_addr));
					p=p->next;
				}
			}
			else if(msg.type=='t')
			{
				node_p p=H->next;
				printf("%s:%s\n",msg.name,msg.text);
				while(p!=NULL)
				{
					msg.type='t';
					if(strcmp(p->name,msg.name)!=0)
					{
						sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&p->cli_addr,sizeof(p->cli_addr));
					}
					p=p->next;
				}
			}
			else if(msg.type=='q')
			{
				printf("\033[1;36m%s离开了聊天室...\n",msg.name);
				node_p p=H->next;
				while(p!=NULL)
				{
					msg.type='q';
					sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&p->cli_addr,sizeof(p->cli_addr));
					p=p->next;
				}
			}
		}
		if(pfd[1].revents==POLLIN)
		{
			msg.type='s';
			bzero(wbuf,sizeof(wbuf));
			fgets(wbuf,sizeof(wbuf),stdin);
			strcpy(msg.text,wbuf);
			msg.text[strlen(msg.text)-1]=0;
			node_p p=H->next;
			while(p!=NULL)
			{
				msg.type='s';
				sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&p->cli_addr,sizeof(p->cli_addr));
				p=p->next;
			}
			printf("\033[1;36m系统消息推送成功。\n");
		}
	}
	close(sfd);
	return 0;
}

客户端

#include <header.h>
int quit_flag=0;
typedef struct msg
{
	char type;
	char name[20];
	char text[128];
}msg;
int main(int argc, const char *argv[])
{
	if(argc!=3)
	{
		printf("\033[1;35m请依次输入正确的ip地址和端口号!\n");
		return 1;
	}
	const char *SER_IP=argv[1];
	int SER_PORT=atoi(argv[2]);
	printf("\033[1;36m请输入用户名:");
	int cfd=socket(AF_INET,SOCK_DGRAM,0);
	if(cfd==-1)
	{
		perror("socket");
		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 addrlen=sizeof(sin);
	struct pollfd pfd[2];   
	pfd[0].fd=0;
	pfd[1].fd=cfd;
	pfd[0].events=POLLIN;
	pfd[1].events=POLLIN;
	msg msg;
	char username[20]={0};
	fgets(username,sizeof(username),stdin);
	strcpy(msg.name,username);
	msg.name[strlen(msg.name)-1]=0;
	msg.type='n';
	sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin));
	char rbuf[128]={0};
	while(1)
	{
		int res=poll(pfd,2,-1);
		if(res==-1)
		{
			perror("poll");
			return 1;
		}
		else if(res==0)
		{
			printf("time out\n");
			return 1;
		}
		if(pfd[0].revents==POLLIN)
		{
			msg.type='t';
			strcpy(msg.name,username);
			msg.name[strlen(msg.name)-1]=0;
			char txt[128]={0};
			bzero(txt,sizeof(txt));
			fgets(txt,sizeof(txt),stdin);
			strcpy(msg.text,txt);
			msg.text[strlen(msg.text)-1]=0;
			int flag=0;
			if(strcmp(msg.text,"quit")==0)
			{
				msg.type='q';
				sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin));
				flag=1;
				quit_flag=1;
			}
			if(flag==0)
			{
				sendto(cfd,&msg,sizeof(msg),MSG_DONTWAIT,(struct sockaddr*)&sin,sizeof(sin));
			}
		}
		if(pfd[1].revents==POLLIN)
		{
			recvfrom(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,&addrlen);
			if(msg.type=='t')
			{
				printf("\033[1;34m%s:\033[0m%s\n",msg.name,msg.text);
			}
			else if(msg.type=='n')
			{
				printf("-----------------\033[1;33m %s \033[1;35m 已上线 \033[1;33m--------------\n",msg.name);
			}
			else if(msg.type=='s')
			{
				printf("\033[1;36msystem:%s\n",msg.text);
			}
			else if(msg.type=='q')
			{
				printf("-----------------\033[1;33m %s\033[1;35m  已下线 \033[1;33m-------------\n",msg.name);
				if(quit_flag==1)
				{
					break;
				}
			}
		}
	}
	close(cfd);
	exit(0);
	return 0;
}

功能实现

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式进阶——HID协议

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 USB烧录USB HID协议USB协议组成通讯流程 官方USB HID范例文件说明修改PC端的显示 兼容库函数HID键盘USB调试工具USB 描述符设备描述…

29-ESP32-S3-WIFI篇-00 STA模式扫描全部 AP

ESP32-S3 WIFI_Driver 引言 ESP32-S3是一款集成了Wi-Fi和蓝牙功能的芯片。关于WIFI的部分&#xff0c;其实内容比我想象的要多得多。所以通常来说&#xff0c;如果你想要编写自己的Wi-Fi应用程序&#xff0c;最快捷的方法就是先找一个类似的示例应用&#xff0c;然后将它的相…

输入与输出的魔法:探索Python的内置函数

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、从键盘捕获输入&#xff1a;input()函数的力量 二、打印输出&#xff1a;print()函数的…

简单模拟实现shell(Linux)

目录​​​​​​​ 前言 展示效果 实现代码 前言 该代码模拟了shell的实现&#xff0c;也就是解析类似于“ls -a -l"的命令&#xff0c;当我们启动我们自己写的shell的可执行程序时&#xff0c;我们输入"ls"的命令&#xff0c;也可以展示出在shell中输入&…

50etf期权购是什么意思?

今天带你了解50etf期权购是什么意思&#xff1f;很多刚刚接触50ETF期权的投资者或许不太明白50ETF期权投资是一种什么样的投资&#xff0c;对于50ETF期权投资来说&#xff0c;有认购合约与认沽合约&#xff0c;那么“购”也就是认购的意思。 50etf期权购是什么意思&#xff1f;…

速看!!24上软考【电子商务设计师】真题回顾,含答案解析

2024上半年软考考试已经结束了&#xff0c;为大家整理了网友回忆版的电子商务设计师真题及答案&#xff0c;25-26日两批考试总共60道题。 上半年考试的宝子们可以对答案预估分数&#xff01;准备下半年考的宝子可以提前把握考试知识点和出题方向&#xff0c;说不定会遇到相同考…

当今世界三个最厉害的人物颜廷利:全球最受欢迎的点赞第一人

我们生活在一个历史的拐点&#xff0c;一个要求我们重新构思自我、解读世界以及预见未来的时代。在这个时代&#xff0c;那些能够洞悉社会发展的深层逻辑&#xff0c;并据此提出全新定义的人&#xff0c;将成为引领人类思维、塑造普遍价值观和主导全球发展议程的先锋。因此&…

插件“猫抓”使用方法 - 浏览器下载m3u8视频 - 合并 - 视频检测下载 - 网课下载神器

前言 浏览器下载m3u8视频 - 合并 - 网课下载神器 chrome插件-猫抓 https://chrome.zzzmh.cn/info/jfedfbgedapdagkghmgibemcoggfppbb 步骤&#xff1a; P.s. 推荐大佬的学习视频&#xff01; 《WEB前端大师课》超级棒&#xff01; https://ke.qq.com/course/5892689#term_id…

01_Spring Ioc DI案例,setter方法和构造方法注入(详解) + 思维导图

文章目录 一.概念实操Maven父子工程 二. IOC和DI入门案例【重点】1 IOC入门案例【重点】问题导入1.1 门案例思路分析1.2 实现步骤2.1 DI入门案例思路分析2.2 实现步骤2.3 实现代码2.4 图解演示 三、Bean的基础配置问题导入问题导入1 Bean是如何创建的【理解】2 实例化Bean的三种…

Java导出excel带图片(希望能帮助你们节省时间)

第一天太慌张&#xff0c;下班逃跑&#xff0c;一夜没睡好&#xff0c;第二天决定搞出来。 查了好多博客&#xff0c;感觉都挺繁琐的&#xff0c;好多工具类、引入类找不到。经过一上午的琢磨&#xff0c;终于搞定。记录一下 借鉴了这个博主的文章 需求前端点击导出按钮&#…

HackTheBox-Machines--Lazy

Lazy测试过程 1 信息收集 1.端口扫描 发现 SSH&#xff08;22&#xff09;、HTTP&#xff08;80&#xff09;端口 nmap -sC -sV 10.129.159.512.访问 80 端口 1.页面中存在注册功能&#xff0c;测试注册功能 页面返回登录页面及用户名 使用burpsuite观察注册请求 /register.p…

骑车不戴头盔监测摄像机

骑行是一种健康的出行方式&#xff0c;但是在骑行途中不戴头盔存在安全隐患&#xff0c;容易造成头部受伤。为了规范骑行行为&#xff0c;保障骑行安全&#xff0c;可以考虑使用骑车不戴头盔监测摄像机进行监测和识别。这种摄像机可以通过智能识别技术&#xff0c;实时监测骑自…

Centos7时区设置及手动修改时间

一、修改系统时区 1、查看时区命令 timedatectl 2、设置时区命令 #下面将时区设置为上海时区 timedatectl set-timezone Asia/Shanghai 3、查看时区看一下新时区有没有生效 timedatectl 二、手动修改系统时间 修改系统时间 date -s "2023-12-25 16:05:10" 查…

串口调试助手中文乱码 解决方案

输出乱码 一般&#xff0c;当串口调试助手输出乱码时&#xff0c;可能有以下几个原因&#xff1a; 波特率设置错误&#xff1a;串口通信需要保证发送和接收的设备使用相同的波特率。请检查串口调试助手和目标设备的波特率设置是否一致。 数据位、停止位或校验位设置错误&…

自建视频托管平台:MediaCMS

目录 1 MediaCMS简介1.1 介绍1.2 特性1.3 应用场景 2 安装配置2.1 安装1、安装2、汉化 2.2 一些常见配置 3 简单使用3.1 上传3.2 下载3.3 添加标题或者字幕3.4 通过Tag/Category实现视频/文件分类添加 Tag给任一资源分类 1 MediaCMS简介 1.1 介绍 MediaCMS是一个现代的&#…

Vue项目运行页面禁止缩放【移动端和PC端都禁止缩放】解决方案

Vue项目运行页面禁止缩放【移动端和PC端都禁止缩放】解决方案&#xff0c;有的人手很J,总喜欢放大缩小&#xff0c;从而会导致页面错乱&#xff0c;以下是解决方案&#xff0c;简单有效 效果图PC&#xff1a;滚轮缩放和其他缩放都会禁止 移动端效果图&#xff1a;各种手机平板…

活动会议邀请函制作易企秀源码系统 清爽的画面轻轻滑动自动翻页 带完整的前后端搭建教程

系统概述 在当今数字化时代&#xff0c;活动会议的组织和宣传变得至关重要。为了满足这一需求&#xff0c;活动会议邀请函制作易企秀源码系统应运而生。它不仅为用户提供了一个便捷、高效的工具&#xff0c;还具备一系列令人瞩目的特色功能&#xff0c;为活动会议的成功举办提…

Redis篇 哈希表在redis中的命令

哈希命令 一.哈希表的基本认识二. 哈希表在redis中的命令1.hset,hget2.hdel3.hkeys,hvals4.hexists5.hgetall6.hmget7.hlen8.hincrby和hincrbyfloat 一.哈希表的基本认识 在JAVA数据结构中&#xff0c;我们就已经接触到了哈希表&#xff0c; 在当时&#xff0c;我们主要用到的哈…

香港Web3媒体:Techub News

Techub News&#xff1a;香港领先&#xff0c;世界一流的科技媒体平台 在数字化时代&#xff0c;Web3技术的崛起为媒体行业注入了新的活力。作为香港领先的Web3媒体平台&#xff0c;Techub News凭借其专业的团队、丰富的资源和创新的业务模式&#xff0c;成为了行业内的佼佼者。…

Go开发Prometheus客户端实战步骤

1、项目背景 在当前的IT运维环境中&#xff0c;我们的业务系统日益复杂&#xff0c;特别是针对特定的业务逻辑和定制化需求&#xff0c;传统的通用监控工具往往难以覆盖所有的监控场景。例如&#xff0c;考虑到一个复杂的电商平台&#xff0c;除了基础的服务器性能、网络状况等…