网络编程第五天

#include 
#define ERR_MSG(msg)do {\
	fprintf(stderr,"__%d__",__LINE__);\
	perror(msg);\
}while(0)
#define PORT 8080
#define IP "192.168.124.62"
int main(int argc, const char *argv[])
{
	//创建流式套接字
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd < 0 )
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("socket create success sfd = %d \n",sfd);
	//允许端口快速被复用
	int reuse = 1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}
	//定义并填充地址信息结构体,给服务器绑定使用
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);

	//绑定服务器自身的地址信息
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("bind");
		return -1;
	}
	printf("bind success __%d__\n",__LINE__);
	//将套接字设定为被动监听状态
	if(listen(sfd,128)<0)
	{
		ERR_MSG("listen");
		return -1;
	}
	printf("listen success __%d__\n",__LINE__);
	//创建一个读集合
	fd_set readfds,tempfds;
	FD_ZERO(&readfds);    //清空集合

	//将需要监听的文件描述符填充到读集合中
	
	FD_SET(0,&readfds);
	FD_SET(sfd,&readfds);

	int s_res = 0;
	char buf[128]="";
	ssize_t res = 0;
	int newfd;
	int maxfd = sfd;
	//接受客户端地址信息
	struct sockaddr_in cin;
	socklen_t addrlen = sizeof(cin);

	while(1)
	{
		tempfds = readfds;
		//调用select IO多路复用函数
		s_res = select(maxfd+1,&tempfds,NULL,NULL,NULL);
		if(s_res<0)
		{
			ERR_MSG("select");
			return -1;
		}
		else if(s_res == 0)
		{
			printf("time out ...\n");
			break;
		}
		//能运行到当前位置,则代表有文件描述符准备就绪
		//判断当前集合中哪个文件描述符准备就绪
		

		for(int i = 0;i<=maxfd;i++)
		{
			if(FD_ISSET(i,&tempfds)==0)
			{
				continue;
			}
			if(i == 0)
			{
				printf("出发键盘输入事件\n");
				fgets(buf,sizeof(buf),stdin);
				buf[strlen(buf)-1] = '\0';
				printf("buf = %s\n",buf);

			}
			else if(i == sfd)
			{
				printf("触发客户端连接事件\n");
				
				
		            deal_cliconnect(sfd,&cin,&readfds,&maxfd)

			}
			else
			{
				printf("触发客户端交互事件\n");
				//获取连接成功的客户端交互信息,生成一个新的套接字
				deal_climsg(i,cin,&readfds,&maxfd);
			}
		}
	}
	return 0;
}


int deal_climsg(int i,struct sockaddr_in pcin,fd_set *preadfds,int *pmaxfd)
{
	char buf[128] = "";
	bzero(buf,sizeof(buf));
	res = recv(i,buf,sizeof(buf),0);
	if(res<0)
	{
		ERR_MSG("recv");
		return -1;
	}
	else if(res == 0)
	{
		printf("[%s:%d]newfd = %d 客户端下线 __%d__\n",\
				inet_ntoa(pcin.sin_addr),ntohs(pcin.sin_port),i,__LINE__);
		close(i);
		FD_CLR(i,preadfds);

		while(FD_ISSET(pmaxfd,*preadfds)==0,(*preadfds)-->0);
		return 0;

	}
	printf("[%s:%d]newfd = %d : %s __%d__\n",\
			inet_ntoa(pcin.sin_addr),ntohs(pcin.sin_port),buf,__LINE__);
	strcat(buf,"o.O");
	if(send(i,buf,sizeof(buf))<0)
	{
		ERR_MSG("send");
		return -1;
	}
	printf("send success __%d__\n",__LINE__);
	return 0;

}

int del_cliconnect(struct sockaddr_in pcin,int newfd,fd_set *preadfds,int *pmaxfd)
{
	socklen_t addrlen = sizeof(*pcin);
	int newfd = accept(sfd,(struct sockaddr*)pcin,&addrlen);
	if(newfd < 0)
	{
		ERR_MSG("accept");
		return -1;
	}
	printf("[%s:%d] newfd = %d 客户端连接成功 __%d__\n",\
			inet_ntoa(pcin.sin_addr),ntohs(pcin.sin_port),newfd,__LINE__);
	FD_SET(newfd,preadfds);
	*pmaxfd = *pmaxfd>newfd ? *pmaxfd:newfd;
	return 0;
}

客户端

#include 

#define PORT 8080
#define IP "192.168.124.62"

int main(int argc, const char *argv[])
{
	//创建流式套接字
	int cfd = socket(AF_INET,SOCK_STREAM,0);
	if(cfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("socket success cfd = %d __%d__\n"cfd __LINE__);

	//定义并填充结构体,给服务器绑定使用
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);

	if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("connect");
		return -1;
	}
	printf("connect success __%d__ \n",__LINE__);

	fd_set readfds,tempfds;
	FD_ZERO(&readfds);
	FD_SET(0,&readfds);
	FD_SET(cfd,&readfds);
	
	int s_res;
	char buf[128]="";
	ssize_t res = 0;
	while(1)
	{
		tempfds = readfds;
		s_res = select(cfd+1,&tempfds,NULL,NULL,NULL);
		if(s_res<0)
		{
			ERR_MSG("select");
			return -1;
		}
		else if(s_res == 0)
		{
			printf("time out...\n");
			break;
		}
		if(FD_ISSET(0,&readfds))
		{
			bzero(buf,sizeof(buf));
			printf("请输入\n");
			fgets(buf,sizeof(buf),stdin);
			buf[strlen(buf)-1]='\0';
			if(send(cfd,buf,sizeof(buf),0)<0)
			{
				ERR_MSG("recv");
				return -1;
			}
			else if(res == 0)
			{
				printf("[%s:%d] 客户端下线 %d __%d__ \n",\
						inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),cfd,__LINE__);
				break;
			}
			printf("[%s:%d] 数据发送成功\n" inet_ntoa(sin.sin_addr),ntohs(sin.sin_port));

		}
	}

   if(close(cfd)<))
   {
	   ERR_MSG("close");
	   return -1;
   }
	return 0;
}

你可能感兴趣的:(网络,github)