UDP网络聊天室服务器端


#include <myhead.h>
#define IP "192.168.2.200"
#define GIP "192.168.2.255"
#define PORT 17688
#define ERR_MSG(msg) do{\
		fprintf(stderr,"line:%d file:%s fun:%s",__LINE__,__FILE__,__func__);\
		perror(msg);\
}while(0);
char usrname[50][10]={};
long ipname[50];
struct message
{
	char type;
	char name[20];
	char text[108];
};
 
int main(int argc, const char *argv[])
{
	//创建流式套接字
	int cfd=socket(AF_INET,SOCK_DGRAM,0);
	if(cfd<0)
	{
		ERR_MSG("socket");	
		return -1;
	}
 
	printf("create socket success\n");
 
	//设置允许广播
	
	int broad=1;
	if(setsockopt(cfd,SOL_SOCKET,SO_BROADCAST,&broad,sizeof(broad))<0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}
	printf("设置允许广播\n");
 
   //允许端口被快速重
	int reuse=1;
	if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}
 
 
 
	struct sockaddr_in sin;
 
	sin.sin_family = AF_INET;             //必须填AF_INET
	sin.sin_port   = htons(PORT);         //1024~49151
	sin.sin_addr.s_addr   = inet_addr(IP);
 
 
 
 
	//绑定服务器ip和端口>>必须绑定
	if(bind(cfd,(struct sockaddr *)&sin,sizeof(sin))<0)
	{
		ERR_MSG("bind");
		return -1;
	}
	printf("bind success __%d__ \n",__LINE__);
	//将套接字设置为被动监听状态
	struct sockaddr_in gin;
 
	gin.sin_family = AF_INET;             //必须填AF_INETgin.sin_port   = htons(2000);         //1024~49151
  gin.sin_port   = htons(PORT);
  	gin.sin_addr.s_addr   = inet_addr(GIP);
 
  //1024~49151
	socklen_t ginlen=sizeof(gin);
	//绑定服务器ip和端口>>必须绑定
/*	if(connect(sfd,(struct sockaddr *)&dstaddr,sizeof(dstaddr))<0)
	{
		ERR_MSG("connect");
		return -1;
	}
*/
	char buf[128] = "";
	char buf1[128] ="";
	char buf2[128]="";
	struct sockaddr_in cin;
	socklen_t addrlen=sizeof(cin);
	int flag,i=0,t=0;
	pid_t pid=fork();
	while(1)
	{
		if(pid>0)//接收请求并广播
		{
			while(1)
			{   int size=0;
				strcpy(buf,"");	
				printf("1:%s",buf);
				bzero(buf,sizeof(buf));
				printf("2:%s",buf);
				bzero(buf2,sizeof(buf)); 
 
				if(recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&addrlen)<0)
				{
					ERR_MSG("recv");
					return -1;
				}
				switch(buf[0])
				{
					case 'C'://群聊消息
								for(i=0;i<50;i++)
								{
									if(ipname[i]==(ntohs(cin.sin_port)))
									{
					            sprintf(buf2,"%s:%s",usrname[i],buf+1);
								//	    printf("%s",buf);
								//		strcat(ipname[i],buf);
								//		strcpy(buf,ipname[i]);
								//		strcpy(ipname[i],temp);
								//
										break;
									
									}
								
								}
							//	printf("1:%d\n",ntohs(cin.sin_port));
								flag=0;
								sendto(cfd,buf2,sizeof(buf2),0,(struct sockaddr*)&gin,sizeof(gin));
							//	printf("广播成功%s\n",buf+1);
								break;
					case 'L'://用户登录
								flag=0;
								for(i=0;i<50;i++)
									if(strcmp(buf+1,usrname[i])==0)
										flag=1;
								
								printf("flag=%d\n",flag);
									if(flag==0){
										for(t=0;t<50;t++)
										{
											if(strcmp(usrname[t],"")==0)
											{
											    strcpy(usrname[t],buf+1);
												ipname[t]=ntohs(cin.sin_port);
												printf("port:%ld\n",ipname[t]);
												break;
											}
										}
									//	strcpy(usrname[t],buf+1);
										strcat(buf+1,"用户登录");
										sendto(cfd,buf+1,sizeof(buf)-1,0,(struct sockaddr*)&gin,sizeof(gin));
									}
									else
									{
										strcat(buf+1,"登录失败!用户已在线,请勿重复登录");
										sendto(cfd,buf+1,sizeof(buf)-1,0,(struct sockaddr*)&gin,sizeof(gin));
 
									}
							//	printf("用户登录成功%s\n",buf+1);
								
 
								break;
					case 'Q'://用户退出
								flag=0;
								strcat(buf+1,"用户退出");
								sendto(cfd,buf+1,sizeof(buf)-1,0,(struct sockaddr*)&gin,sizeof(gin));
							//	printf("用户退出%s\n",buf+1);
 
								break;
					default://无效的消息
						break;
				}
			}
	
		}else if(pid==0)//广播系统消息
		{while(1){
				bzero(buf1,sizeof(buf1));
				strcpy(buf1,"");
				fgets(buf1,sizeof(buf1),stdin);
				buf1[strlen(buf1)-1]='\0';
				sendto(cfd,buf1,sizeof(buf1),0,(struct sockaddr*)&gin,sizeof(gin));
				printf("系统消息发送成功\n");
				 }
		}else
		{
			ERR_MSG("FORK");
			return -1;
		}
	}
 
	close(cfd);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值