UDP网络聊天室(更)

服务器端

cs 复制代码
#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;
}

客户端

cs 复制代码
#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;
}

功能实现

相关推荐
小林熬夜学编程18 分钟前
【Linux网络编程】第十四弹---构建功能丰富的HTTP服务器:从状态码处理到服务函数扩展
linux·运维·服务器·c语言·网络·c++·http
Hacker_Fuchen20 分钟前
天融信网络架构安全实践
网络·安全·架构
上海运维Q先生22 分钟前
面试题整理15----K8s常见的网络插件有哪些
运维·网络·kubernetes
ProtonBase32 分钟前
如何从 0 到 1 ,打造全新一代分布式数据架构
java·网络·数据库·数据仓库·分布式·云原生·架构
fantasy_arch10 小时前
CPU性能优化-磁盘空间和解析时间
网络·性能优化
njnu@liyong11 小时前
图解HTTP-HTTP报文
网络协议·计算机网络·http
是Dream呀12 小时前
Python从0到100(七十八):神经网络--从0开始搭建全连接网络和CNN网络
网络·python·神经网络
kaixin_learn_qt_ing13 小时前
了解RPC
网络·网络协议·rpc
安全小王子13 小时前
Kali操作系统简单介绍
网络·web安全
Hacker_LaoYi15 小时前
【漏洞分析】DDOS攻防分析(四)——TCP篇
网络·tcp/ip·ddos