UDP 双层select实现多端口输入,至少有一个端口有数据来时再做处理

接收:

int main()
{
	int fd[4]={0,0,0,0},max_fd = 0;
	
	int i;
	int ret;
	int addr_len;
	struct sockaddr_in saddr,caddr;
	char buf[4][1024];

	for(i=0;i<4;i++)
	{

		fd[i]=socket(AF_INET,SOCK_DGRAM,0);
		if(fd[i]<0)
		{
			perror("socket");
		}
		saddr.sin_family=AF_INET;
		saddr.sin_port=htons(9000+i);
		inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr.s_addr);
	
	
		ret=bind(fd[i],(struct sockaddr*)&saddr,sizeof(saddr));
		if (ret<0)
		{
			perror("bind");
		}

	}

	fd_set set,rset;

	addr_len=sizeof(caddr);
	struct timeval tv;
		FD_ZERO(&set);
		FD_ZERO(&rset);
		FD_SET(fd[0],&set);
		FD_SET(fd[1],&set);
		FD_SET(fd[2],&set);
		FD_SET(fd[3],&set);
	
		fd[0] > fd[1] ? (max_fd=fd[0]):(max_fd=fd[1]);
		fd[2] > max_fd ? (max_fd=fd[2]):(max_fd=max_fd);
		fd[3] > max_fd ? (max_fd=fd[3]):(max_fd=max_fd);
		printf("%d %d %d %d %d\n",fd[0],fd[1],fd[2],fd[3],max_fd);
		
	while(1)
	{

		rset=set;
		int flag_fd[4]={0,0,0,0};
		
		ret=select(max_fd+1,&rset,NULL,NULL,NULL);
		printf("into select ...\n");	
		if(ret<0)
		{
			perror("select");
			break;
		}

		for(i=0;i<4;)
		{
			if(FD_ISSET(fd[i],&rset))break;
			else i++;

		}flag_fd[i]++;
		//printf("---------fd[%d] = %d flag[%d] = % d\n",i,fd[i],i,flag_fd[i]);
		bzero(buf[i],1024);
		ret=recvfrom(fd[i],buf[i],1024,0,(struct sockaddr*)&caddr,&addr_len);
		if(ret==-1)
		{
			perror("rcecvfrom");
		}
		
		printf("----------recvfrom 900%d:%s\n",i,buf[i]);	

		while(1)
		{
	
			rset=set;
			tv.tv_sec=10;
            tv.tv_usec=0;     //在某些电脑上不设置usec会无限阻塞
			ret=select(max_fd+1,&rset,NULL,NULL,&tv);
			if(ret<0)
			{
				perror("select");
				continue;
			}
			if(FD_ISSET(fd[0],&rset)||FD_ISSET(fd[1],&rset)||FD_ISSET(fd[2],&rset)||FD_ISSET(fd[3],&rset))
			{
				for(i=0;i<4;)
				{
					if(FD_ISSET(fd[i],&rset))break;
					else i++;
				}

				bzero(buf[i],1024);
				ret=recvfrom(fd[i],buf[i],1024,0,(struct sockaddr*)&caddr,&addr_len);
				if(ret==-1)
				{
					perror("rcecvfrom");
				}
				flag_fd[i]++;
				printf("recvfrom 900%d:%s\n",i,buf[i]);
				if((flag_fd[0]+flag_fd[1]+flag_fd[2]+flag_fd[3])>3)goto TIME_OVER;
				continue;
			}

TIME_OVER:
			printf("............................\n");
			printf("buf[0]:%s  buf[1]:%s  buf[2]:%s  buf[3]:%s\n",buf[0],buf[1],buf[2],buf[3]);
			for(i=0;i<4;i++)
			{			
				bzero(buf[i],1024);
			}
			break;

		}

	

	}

发送:

int main(int argc,char *argv[])
{
		int fd;int saddr_len;
		int ret;
		char buf[1024];
		struct sockaddr_in saddr;
		int port = atoi(argv[1]);
		fd = socket(AF_INET, SOCK_DGRAM, 0);
		if(fd < 0)
		{
				printf("create socket fail!\n");
				return -1;
		}

		saddr.sin_family=AF_INET;
		saddr.sin_port=htons(port);
		inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr.s_addr);
	int i =0;

		while(1)
		{

			printf("input:");
			scanf("%s",buf);
		
			ret=sendto(fd,buf,1024,0,(struct sockaddr*)&saddr,sizeof(saddr));

		}

		close(fd);

		return 0;
}

实现的功能,四个发送方,接收方从接收到第一个数据开始,用10s的时间来进行数据接收,如果10s时间到或者累计输入已经到达4次,那么数据接收完成。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值