UDP通信流程

UDP通信流程

描述

UDP没有所谓的服务器与客户端,只需双方绑定对方的Ip和端口号即可。

步骤

一、先初始化本地以及对方IP以及端口号

char hostIp[32];
char localIp[32];
int	hostport;
int	localport;

本地IP及端口号设置

1. struct  sockaddr_in  Mcast_addr;
2.bzero(&localIp[0],32);	
3.sprintf(localIp,"192.168.2.200",);	
4.localport = 50001;
5.Mcast_addr.sin_family = AF_INET;
6.Mcast_addr.sin_addr.s_addr = inet_addr(localIp);	//本地端口号
7.Mcast_addr.sin_port = htons(localport);	//本地IP

对方IP及端口号设置

1.struct  sockaddr_in  Host_addr;
2.bzero(&hostIp[0],32);	
3.sprintf(hostIp,"192.168.2.200",);	
4.hostport = 40001;
5.Host_addr.sin_family = AF_INET;
6.Host_addr.sin_addr.s_addr = inet_addr(hostIp);	//对方端口号
7.Host_addr.sin_port = htons(hostport);	//对方IP

二、建立连接

	if ( (socketfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 )
	{	
		perror("建立失败\r\n");
		return ;
	}
	else
	{
		printf("建立成功\r\n");
		//绑定端口号,否则本地每次对外发送一次数据,端口号就会随机改变
		bind(socketfd, (struct sockaddr *)&Mcast_addr, sizeof(Mcast_addr));		
	}

三、发送数据(本地)

temp_buf 所要发送的数据缓冲区
addrlen sizeof(Host_addr)
Host_addr 对方IP地址
sendnum 发送的数据长度
sendto(socketfd,temp_buf,sendnum,0,(struct sockaddr*)&Host_addr,addrlen);

四、接收数据(本地)

fd_set readskt;
FD_ZERO(&readskt);
FD_SET(socketfd,&readskt);

ret = select(socketfd+1,&readskt,NULL,NULL,&time_out);	
if(ret > 0)
{
RecvLen = recvfrom(socketfd, RecvBuf, MAXDATASIZE, 0,NULL,NULL);
}

整体流程


void Cnetwork::initial(portcfg_t * hostportinfo)
{
	//将组播地址加入到路由表
	system("route add -net 224.1.0.1 netmask 255.255.255.255 eth1");
	
}

void Cnetwork:: GetData()
{
	char RecvBuf[MAXDATASIZE];
	int i,numbytes;
	int  RecvLen = 0;
	int ret,retUDPgroup,retUDPsingle=0;
	int maxfd;
	int addr_len;
	fd_set readskt,readsktUDPgroup,readsktUDPsingle;
	struct timeval time_out;

	FD_ZERO(&readsktUDPsingle);
	FD_ZERO(&readsktUDPgroup);
	time_out.tv_sec =0;
	time_out.tv_usec = 400000;


	FD_SET(socketfd_udp_single,&readsktUDPsingle);
	FD_SET(mcastsocketfd,&readsktUDPgroup);
	ret = 0;

	retUDPsingle = select(socketfd_udp_single+1,&readskt,NULL,NULL,&time_out);
	retUDPgroup = select(mcastsocketfd+1,&readsktUDPgroup,NULL,NULL,&time_out);
	
	
	if (( ret > 0)||( retUDPgroup > 0)||(retUDPsingle>0) )
	{	
		if((netmode == 0)&&( ret > 0))
		{
			RecvLen = recv(socketfd, RecvBuf,MAXDATASIZE,0);
		}
		else 
		{	
			if(retUDPsingle>0)
			{
				printf("UDP接收到单播数据\r\n");
				RecvLen = recvfrom(socketfd_udp_single, RecvBuf, MAXDATASIZE, 0,NULL,NULL);
			}
			else if(retUDPgroup>0)
			{
				printf("UDP接收到多播数据\r\n");
				addr_len = sizeof(Local_addr);
				RecvLen = recvfrom(mcastsocketfd, RecvBuf, MAXDATASIZE, 0,(struct sockaddr*)&Local_addr,(socklen_t*)&addr_len);
			}
		}
		if ( RecvLen > 0 )
		{
			time_t tp;
			struct tm * lt;	
			time(&tp);
			lt=localtime(&tp);	
			printf("\r\n");			
			printf("net udp receive time= %d年%d月%d日%d时%d分%d秒\r\n",(lt->tm_year-100+2000),(lt->tm_mon+1),lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_sec);	
			printf("recv byte = %d \r\n",RecvLen);
			printf("receive: ");
			for ( i = 0; i < RecvLen; i++ )
			{
				printf("%2.2X ",(unsigned char)RecvBuf[i]);
			}
			printf("\n\n");
			
			for ( i = 0; i < RecvLen; i++ )
			{
				putdata(&HostInfo->sendtoapp_dataque, RecvBuf[i]);
			}
		}
		else if ( RecvLen == 0 )
		{
			printf("recv_len = 0\n");
			CloseConnect();
	
		}
		else
		{
			if ( errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN )
			{
			}
			else
			{
				printf("recv_len < 0\n");
				CloseConnect();
		
			}
		}
		timeout_num = 0;
	}
}

void Cnetwork::SendData()
{
	char temp_buf[MAXDATASIZE];
	int i,sendnum;
	int addrlen;
	
	if ( (sendnum = HostInfo->recfromapp_dataque.count) > 0 )
	{
		for ( i = 0; i < sendnum; i++ )
		{
			temp_buf[i] = HostInfo->recfromapp_dataque.buf[mod(HostInfo->recfromapp_dataque.start+i,HostInfo->recfromapp_dataque.size)];
		}
	}
	if ( sendnum > 0 )
	{
		if(netmode == 1)
		{
			addrlen = sizeof(Host_addr);
			
			if ( (sendnum = HostInfo->recfromapp_dataque.count) > 0 )
			{	
				
				time_t tp;
				struct tm * lt; 
				time(&tp);
				lt=localtime(&tp);	
				printf("\r\n"); 		
				printf("net send time= %d年%d月%d日%d时%d分%d秒\r\n",(lt->tm_year-100+2000),(lt->tm_mon+1),lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_sec);	
				printf("need byte = %d \r\n",sendnum);
				for ( i = 0; i < sendnum; i++ )
				{
					temp_buf[i] = HostInfo->recfromapp_dataque.buf[mod(HostInfo->recfromapp_dataque.start+i,HostInfo->recfromapp_dataque.size)];
					printf("%2.2X ",(unsigned char)temp_buf[i]);
				}
				printf("\r\n");
			}
			int sendlen = sendto(socketfd_udp_single ,temp_buf,sendnum,0,(struct sockaddr*)&Host_addr,addrlen);//mark
			for ( i = 0; i < sendnum; i++ )
			{
				dropdata(&HostInfo->recfromapp_dataque);
			}
	
		}
	}
}

void Cnetwork::CreatConnect()
{	
	char McastIp[32];
	char localIp[32];
	char hostIp[32];
	printf("CreatConnect enter \r\n");
	if ( socketfd == -1 )	//100128-jxy
	{
		printf("netmode = %d\r\n",netmode);
	
		//创建UDP单播套接字
		if(netmode == 1)//UDP
		{
			if ( (socketfd_udp_single = socket(AF_INET, SOCK_DGRAM, 0)) == -1 )
			{	
				perror("Error connecting to socket\n");
				return ;
			}
			else
			{
				printf("<<<<<<<<<Net Mode UDP>>>>>>>>>\r\n");
				bind(socketfd_udp_single, (struct sockaddr *)&Local_addr, sizeof(Local_addr));		//绑定端口号,否则本机端口号一直改变
			}
		}
		
	}
	//多播配置
	if(mcastsocketfd == -1)
	{
		if(netmode== 1)//UDP
		{	
			if ( (mcastsocketfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 )
			{	
				printf("Error connecting to mcastsocketfd\n");
				perror("Error connecting to mcastsocketfd\n");
				return ;
			}
			else
			{	
				printf("<<<<<<<<<Net Mode UDP zubo>>>>>>>>>\r\n");
				int yes = 1;
				if(setsockopt(mcastsocketfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes))<0)
				{
					printf("reusing ADDR failed\r\n");
				}
				
				memset(McastIp,0,32);
				sprintf(McastIp,"224.1.0.1");
				//初始化本地地址
				memset(&Local_addr, 0, sizeof(Local_addr));
				Local_addr.sin_family = AF_INET;
				Local_addr.sin_addr.s_addr =  htonl(INADDR_ANY);
				Local_addr.sin_port = htons(2000);
				
				//绑定socket
				int err = bind(mcastsocketfd,(struct sockaddr*)&Local_addr, sizeof(Local_addr)) ;
				if(err < 0)
				{	
					printf("bind()");
					perror("bind()");
					exit(1);
				}
					
				int loop = 1;
				
	    		err = setsockopt(mcastsocketfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
				if(err<0)
				{
					printf("setsockeopt():IP_MULTICAST_LOOP\r\n");
				}
				
				//将本机加入多播组
				struct ip_mreq	mreq;	
				memset (&mreq, 0, sizeof(mreq));
				mreq.imr_multiaddr.s_addr = inet_addr(McastIp);
				mreq.imr_interface.s_addr = htonl(INADDR_ANY);
			
				err = setsockopt(mcastsocketfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));
				if(err<0)
				{	
					perror("setsockopt():IP_ADD_MEMBERSHIP");
					printf("setsockeopt():IP_ADD_MEMBERSHIP,err = %d\r\n",err);
				}		
			}
		}
	}
	
}
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汤梦飞123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值