12.24

 client

#include 
//定义信息结构体
struct Msg
{
	char type;
	char name[20];
	char text[128];
};
int main(int argc, const char *argv[])
{
	//终端输入服务端ip地址及端口号
	if(argc!=3)
	{
		printf("输入错误!!!!\n");
		printf("请输入ip地址及端口号\n");
		return -1;
	}
	//创建套接字
	int cfd=socket(AF_INET,SOCK_DGRAM,0);
	if(cfd==-1)
	{
		perror("socket error");
		return -1;
	}
	//填充服务端信息地址结构体
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_addr.s_addr=inet_addr(argv[1]);
	sin.sin_port=htons(atoi(argv[2]));
	socklen_t socklen=sizeof(sin);
	//定义收发消息结构体
	struct Msg send_msg;
	struct Msg recv_msg;

	//先登录
	printf("请输入姓名>>");
	send_msg.type='L';
	char name[20]="";
	fgets(name,sizeof(name),stdin);
	name[strlen(name)-1]=0;
	strcpy(send_msg.name,name);

	//给服务端发上线消息
	sendto(cfd,&send_msg,sizeof(send_msg),0,(struct sockaddr*)&sin,sizeof(sin));
	//定义检测文件描述符集合
	fd_set readfds,tempfds;
	FD_ZERO(&readfds);
	FD_SET(cfd,&readfds);
	FD_SET(0,&readfds);
	//接收select返回值
	int res=0;
	while(1)
	{
		tempfds=readfds;
		//检测集合中是否有事件发生
		res=select(cfd+1,&tempfds,NULL,NULL,NULL);
		if(res==-1)
		{
			perror("select error");
			return -1;
		}else if(res==0)
		{
			printf("time out\n");
			return -1;
		}
		//触发终端输入
		if(FD_ISSET(0,&tempfds))
		{
			//把输入内容存储到发送消息结构体中
			bzero(send_msg.text,sizeof(send_msg.text));
			fgets(send_msg.text,sizeof(send_msg.text),stdin);
			send_msg.text[strlen(send_msg.text)-1]=0;
			//quit退出客户端
			if(strcmp(send_msg.text,"quit")==0)
			{
				send_msg.type='Q';
				sendto(cfd,&send_msg,sizeof(send_msg),0,(struct sockaddr*)&sin,sizeof(sin));
				close(cfd);
				break;
			}else 
			{
				send_msg.type='C';
				sendto(cfd,&send_msg,sizeof(send_msg),0,(struct sockaddr*)&sin,sizeof(sin));
			}
		}
		//触发接收消息
		if(FD_ISSET(cfd,&tempfds))
		{
			bzero(recv_msg.text,sizeof(recv_msg.text));
			res=recvfrom(cfd,&recv_msg,sizeof(recv_msg),0,NULL,NULL);
			if(res<0)
			{
				perror("recvfrom error");
				return -1;
			}
			if(recv_msg.type=='L')
			{
				printf("---%s已上线---\n",recv_msg.name);
			}
			if(recv_msg.type=='Q')
			{
				printf("---%s已下线---\n",recv_msg.name);
			}
			if(recv_msg.type=='C')
			{
				printf("%s:%s\n",recv_msg.name,recv_msg.text);
			}
		}
	}
	close(cfd);
	return 0;
}

 serve

#include 
//信息结构体
struct Msg
{
	char type;
	char name[20];
	char text[128];
};
int main(int argc, const char *argv[])
{
	//判断从终端输入字符串的个数
	if(argc!=3)
	{
		printf("输入错误!!!\n");
		printf("请输入ip地址及端口号\n");
		return -1;
	}
	int sfd=-1;
	if((sfd=socket(AF_INET,SOCK_DGRAM,0))==-1)
	{
		perror("socket error");
		return -1;
	}
	int reuse=1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
	{
		perror("setsockopt error");
		return -1;
	}
	//用终端输入ip及端口号填充服务器地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(atoi(argv[2]));
	sin.sin_addr.s_addr=inet_addr(argv[1]);
	//绑定服务器地址信息
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
	{
		perror("bind error");
		return -1;
	}
	//创建客户端地址信息结构体用于接收客户端信息
	struct sockaddr_in cin;
	socklen_t socklen=sizeof(cin);
	struct sockaddr_in arr_cin[1024];
	
	//定义检测文件描述符集合
	fd_set readfds,tempfds;
	FD_ZERO(&readfds);
	FD_SET(0,&readfds);
	FD_SET(sfd,&readfds);
	//接收select返回值
	int res=-1;
	//接收recvfrom返回值
	int count=0;
	int index=0;
	//发送消息容器
	char buf[128]="";
	//定义收发消息结构体
	struct Msg recv_msg;
	struct Msg send_msg;
	while(1)
	{
		tempfds=readfds;
		//检测集合中是否有事件发生
		res=select(sfd+1,&tempfds,NULL,NULL,NULL);
		if(res==0)
		{
			printf("time out\n");
			return -1;
		}else if(res==-1)
		{
			perror("select error");
			return -1;
		}
		//接收到消息
		if(FD_ISSET(sfd,&tempfds))
		{
			count=recvfrom(sfd,&recv_msg,sizeof(recv_msg),0,(struct sockaddr*)&cin,&socklen);
			if(count==-1)
			{
				perror("recvfrom error");
				return -1;
			}
			//收到消息类型为登录型
			if(recv_msg.type=='L')
			{
				//把当前客户端放入客户端数组下标为index的位置
				arr_cin[index]=cin;
				index++;
				//上线格式
				sprintf(buf,"---%s已上线---\n",recv_msg.name);
				printf("%s\n",buf);
				//把上线消息发送给其他客户端
				for(int i=0;i<=index;i++)
				{
					//不发给发信息的客户端
					if(arr_cin[i].sin_port==cin.sin_port)
					{
						continue;
					}
					sendto(sfd,&recv_msg,sizeof(recv_msg),0,(struct sockaddr*)&arr_cin[i],sizeof(arr_cin[i]));
				}
			}
			//收到消息类型为聊天型
			if(recv_msg.type=='C')
			{
				//把接收到的消息发给其他客户端
				send_msg.type=recv_msg.type;
				strcpy(send_msg.name,recv_msg.name);
				strcpy(send_msg.text,recv_msg.text);
				for(int i=0;i

 12.24_第1张图片

你可能感兴趣的:(服务器,前端,算法)