网络编程day6

2. 基于UDP的网络聊天室

项目需求:

  1. 如果有用户登录,其他用户可以收到这个人的登录信息
  2. 如果有人发送信息,其他用户可以收到这个人的群聊信息
  3. 如果有人下线,其他用户可以收到这个人的下线信息
  4. 服务器可以发送系统信息

服务器代码

#include<myhead.h>
#define IP "10.102.137.50 "
#define L 1
#define C 2
#define Q 3
int flag=0;	
struct sockaddr_in savecin[1024];
struct msg
{
	int  type;
	char name[20];
	char text[128];
};
int myrecv(int sfd,struct sockaddr_in savecin[],int flag,struct sockaddr_in cin);
int mysend(int sfd,struct sockaddr_in *savecin,socklen_t addrlen,int flag);
void handler (int sig)
{
	while(waitpid(-1,NULL,WNOHANG)>0);
}
int main(int argc, const char *argv[])
{
	if(signal(17,handler)==SIG_ERR)
	{
		perror("signal error");
		return -1;
	}
	//创建报式套接字  socket
	int sfd=socket(AF_INET,SOCK_DGRAM,0);
	if(sfd<0)
	{
		perror("socket error");
		return -1;
	}
	printf("socket success,sfd=%d\n",sfd);


	//绑定IP地址和端口号   bind
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(6789);
 	sin.sin_addr.s_addr=inet_addr(IP);	
	if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin))<0)
	{
		perror("bind error");
		return -1;
	}
	printf("bind success\n");

	savecin[0]=sin;
	struct sockaddr_in cin;
	socklen_t addrlen=sizeof(cin);
	pid_t pid;

	//定义监测的合集
	struct pollfd fds[2];
	memset(fds,0,sizeof(fds));

	//添加需要的文件描述符
	fds[0].fd=0;
	fds[0].events=POLLIN;

	fds[1].fd=sfd;
	fds[1].events=POLLIN;

	struct msg buf;
	int p_res=-1,nfds=2;
	ssize_t res=0;

	pid=fork();
	if(pid<0)
	{
		perror("fork error");
		return -1;
	}
	else if(pid==0)     //子进程
	{
		//从终端的到数据 群发消息
		mysend(sfd,savecin,addrlen,flag);
		exit(0);
	}
	else
	{
		myrecv(sfd,savecin,flag,cin);
	}



	//关闭套接字,释放资源    close
	close(sfd);
	return 0;
}

int mysend(int sfd,struct sockaddr_in *savecin,socklen_t addrlen,int flag)
{
	struct msg buf={htonl(C),"系统"};
	while(1)
	{
		bzero(buf.text,sizeof(buf.text));
		fgets(buf.text,sizeof(buf.text),stdin);
		buf.text[strlen(buf.text)-1]=0;
		for(int i=0;i<=flag;i++)
		{
			if(sendto(sfd,&buf,sizeof(buf),0,(struct sockaddr *)&savecin[i],addrlen)<0)
			{
				perror("sandto error");
				return -1;
			}
		}
	}
	return 0;
}

int myrecv(int sfd,struct sockaddr_in savecin[],int flag,struct sockaddr_in cin)
{
	int i=0,j=0;
	char buf1[256];
	struct msg buf;
	socklen_t addrlen=sizeof(cin);
	while(1)
	{
		if(recvfrom(sfd,&buf,sizeof(buf),0,(struct sockaddr *)&cin,&addrlen)<0)
		{
			perror("recvfrom error");
			return -1;
		}
		printf("recvfrom success\n");
		printf("%s\n",buf.name);
		int type=ntohl(buf.type);
		switch(type)
		{
		case L:
			flag=flag+1;
			savecin[flag]=cin;
			printf("%s登陆成功\n",buf.name);
			bzero(buf1,sizeof(buf1));
			sprintf(buf1,"%s登陆成功",buf.name);
			for(i=1;i<flag;i++)
			{
				if(sendto(sfd,buf1,sizeof(buf1),0,(struct sockaddr *)&savecin[i],sizeof(savecin[i]))<0)
				{
					perror("sendto error");
					return -1;
				}
			}
			printf("添加成功\n");
			break;
		case C:
			bzero(buf1,sizeof(buf1));
			sprintf(buf1,"%s:%s",buf.name,buf.text);
			for(i=1;i<=flag;i++)
			{
				if(memcmp(&savecin[i],&cin,sizeof(savecin[i])))
				{
					if(sendto(sfd,buf1,sizeof(buf1),0,(struct sockaddr *)&savecin[i],sizeof(savecin[i]))<0)
					{
						perror("sendto error");
						return -1;
					}
				}
			}
			break;
		case Q:
			bzero(buf1,sizeof(buf1));
			sprintf(buf1,"%s删除成功\n",buf.name);		
			for(i=1;i<=flag;i++)
			{
				if(memcmp(&savecin[i],&cin,sizeof(savecin[i]))==0)
				{
					printf("*********************\n");
					//是删除信息
					for(j=i;j<flag;j++)
					{
						savecin[j]=savecin[j+1];
					}
					flag=flag-1;
				}
			}
			printf("%d\n",flag);
			for(i=1;i<=flag;i++)
			{
				if(sendto(sfd,buf1,sizeof(buf1),0,(struct sockaddr *)&savecin[i],sizeof(savecin[i]))<0 )
				{
					perror("sendto error");
					return -1;
				}
			}
			printf("删除成功\n");
			break;
		}
	}
}

客户端代码

#include<myhead.h>
#define IP "10.102.137.50 "
#define L 1
#define C 2
#define Q 3
struct msg
{
	int  type;
	char name[20];
	char text[128];
};
//处理子进程
void handler (int sig)
{
	while(waitpid(-1,NULL,WNOHANG)>0);
}
int mysend(int sfd,struct msg buf,struct sockaddr_in cin);
int myrecv(int sfd);
int main(int argc, const char *argv[])
{
	if(signal(17,handler)==SIG_ERR)
	{
		perror("signal error");
		return -1;
	}

	//创建报式套接字  socket
	int sfd=socket(AF_INET,SOCK_DGRAM,0);
	if(sfd<0)
	{
		perror("socket error");
		return -1;
	}
	printf("socket success,sfd=%d\n",sfd);

	struct sockaddr_in cin;
	cin.sin_family=AF_INET;
	cin.sin_port=htons(6789);
 	cin.sin_addr.s_addr=inet_addr(IP);	
	socklen_t addrlen=sizeof(cin);


	struct msg buf;
	buf.type=htonl(L);
	printf("%d\n",buf.type);
	printf("请输入姓名:");
	fgets(buf.name,sizeof(buf.name),stdin);
	buf.name[strlen(buf.name)-1]=0;
	//发送数据,要指定发送的人  sendto
	if(sendto(sfd,&buf,sizeof(buf),0,\
				(struct sockaddr *)&cin,addrlen)<0)
	{
		perror("sendto error");
		return -1;
	}
	printf("sendto success\n");
	pid_t pid =fork();
	if(pid>0)
	{
		mysend(sfd,buf,cin);
	}
	else if(0==pid)
	{
		myrecv(sfd);
	}

	close(sfd);
	return 0;
}
int mysend(int sfd,struct msg buf,struct sockaddr_in cin)
{
	while(1)
	{

		bzero(buf.text,128);
		fgets(buf.text,128,stdin);
		buf.text[strlen(buf.text)-1]=0;

		if(strcmp(buf.text,"quit")==0)
		{
			buf.type=htonl(Q);
		}else
		{
			buf.type=htonl(C);
		}
		if(sendto(sfd,&buf,sizeof(buf),0,\
	 				(struct sockaddr *)&cin,sizeof(cin))<0)
		{
			perror("recvfrom error");
			return -1;
		}
		if(buf.type==htonl(Q))
		{
			exit(0);
		}
	}

}

int myrecv(int sfd)
{
	char buf[256];
	while(1)
	{
		if(recvfrom(sfd,buf,sizeof(buf),0,NULL,NULL)<0)
		{
			perror("recvfrom error");
			return -1;
		}
		printf("%s\n",buf);
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值