添加组播通信,传输数据

1.添加组播通信,通过组播传输升级数据,写的不好请见谅(仅供学习参考)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <fcntl.h>


#define MAX_BUFFER_SIZE 1024    //根据实际数据大小修改,下同
#define MAX_PACK_SIZE 2
#define MAX_NUM_SIZE 2
#define MAX_ALLNUM_SIZE 2
#define MAX_HW_SIZE 2
#define MAX_SW_SIZE 2
#define MAX_CHK_SIZE 2
#define MAX_ALLCHK_SIZE 2
#define MAX_VALID_SIZE 2

#define MAX_NUM_OFFSET 2    //根据实际数据偏移量修改,下同
#define MAX_ALLNUM_OFFSET 2
#define MAX_CHK_OFFSET 2
#define MAX_ALLCHK_OFFSET 2
#define MAX_HW_OFFSET 2
#define MAX_SW_OFFSET 2
#define MAX_VALID_OFFSET 2
#define MAX_DATA_OFFSET 2
#define MULTICAST_ADDR "address" // 组播地址ַ
#define PORT port // port为组播端口
#define HW "" 
#define	SW ""


int easy_multicast_create(unsigned char **ppFileData//根据实际情况修改, long * pDataLen) {
	int ret = 0;
	int sockfd;
	int i = 0,j = 0;
	int len = 0;
	int FileDataFlag = 0;
	unsigned char *pData = NULL;
	unsigned char *chkFileData = NULL;
	int32_t hexIntNum,hexIntAllNum,CHK1,ALLCHK1,ValidData;
    struct sockaddr_in addr;
    struct ip_mreq mreq;
    char buffer[MAX_BUFFER_SIZE];
	char NUM[MAX_NUM_SIZE],ALLNUM[MAX_ALLNUM_SIZE],HW_VER[MAX_HW_SIZE],
		SW_VER[MAX_SW_SIZE],CHK[MAX_CHK_SIZE],ALLCHK[MAX_ALLCHK_SIZE],Valid[MAX_VALID_SIZE];
	
	if (NULL == ppFileData || NULL == pDataLen)
	{
		return -1;
	}

	*ppFileData = NULL;
	*pDataLen =0;
	
	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 
	{
	     perror("socket");
	     ret =-1;
	     return ret;
	}
	
	// 将套接字设置为非阻塞模式
	int flags = fcntl(sockfd, F_GETFL, 0);
	flags |= O_NONBLOCK;
	fcntl(sockfd, F_SETFL, flags);

	// 设置套接字选项,允许多个进程绑定到同一个组播地址
	int reuse = 1;
	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0) 
	{
	    perror("setsockopt");
	    close(sockfd);
	    ret =-1;
	    return ret;
	}
		
	// 绑定到本地地址和端口
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr.sin_port = htons(PORT);
	if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) 
	{
	    perror("bind");
	    close(sockfd);
	    ret =-1;
	    return ret;
	}

	// 加入组播组
	mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_ADDR);
	mreq.imr_interface.s_addr = htonl(INADDR_ANY);
	if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) 
	{
		perror("setsockopt");
	    close(sockfd);
	    ret =-1;
	    return ret;
	}
		
	while (1)
	{
        // 接收数据
		if (j < 5)
		{
       		ssize_t num_bytes = recvfrom(sockfd, buffer, MAX_BUFFER_SIZE, 0, NULL, 0);
			if (num_bytes < 0) 
			{
				j++;
				usleep(200*1000);//延时
				continue;
        	}
			else
			{	
				j = 0;
			}
		}
		else
		{	
			if (pData)
			{
				free(pData);
			}
			
			if (chkFileData)
			{
				free(chkFileData);
			}

			close(sockfd);
			ret = -1;
            return ret;
		}
//下方为数据具体操作,根据需求修改代码
		//此为将数据取出转为整型数据,便于判断
		memcpy(NUM, buffer+MAX_NUM_OFFSET, MAX_NUM_SIZE);
		memcpy(&hexIntNum, NUM, sizeof(int32_t));
		memcpy(ALLNUM, buffer+MAX_ALLNUM_OFFSET, MAX_ALLNUM_SIZE);
		memcpy(&hexIntAllNum, ALLNUM, sizeof(int32_t));
		memcpy(CHK, buffer+MAX_CHK_OFFSET, MAX_CHK_SIZE);
		memcpy(&CHK1, CHK, sizeof(unsigned int));
		memcpy(ALLCHK, buffer+MAX_ALLCHK_OFFSET, MAX_ALLCHK_SIZE);
		memcpy(&ALLCHK1, ALLCHK, sizeof(unsigned int));
		memcpy(HW_VER, buffer+MAX_HW_OFFSET, MAX_HW_SIZE);
		memcpy(SW_VER, buffer+MAX_SW_OFFSET, MAX_SW_SIZE);
			
		if (strcmp(HW_VER, HW) != 0 || strcmp(SW_VER, SW) == 0) 
		{	
			if (pData)
			{
				free(pData);
			}
			
			if (chkFileData)
			{
				free(chkFileData);
			}
			
			close(sockfd);
			ret = -1;
			return ret;
		}
		
		if (FileDataFlag == 0)
		{	
			FileDataFlag = 1;
			pData = malloc(hexIntAllNum*MAX_PACK_SIZE);
			
			if (!pData)
			{
				ret =-1;
				close(sockfd);
				return ret;
			}
			
			chkFileData = malloc(hexIntAllNum);
			
			if (!chkFileData)
			{
				ret =-1;
				free(pData);
				close(sockfd);
				return ret;
			}
			
			memset(chkFileData,0,hexIntAllNum);
		}
		
		if (chkFileData[hexIntNum] != 1 && CHK1 == easy_hash_Crc32_GetResult(buffer+MAX_DATA_OFFSET,MAX_PACK_SIZE))
		{	
			if (hexIntNum != hexIntAllNum-1)
			{
				memcpy(pData+hexIntNum*MAX_PACK_SIZE, buffer+MAX_DATA_OFFSET, MAX_PACK_SIZE);
				len += MAX_PACK_SIZE;
				
			}
			else
			{
				memcpy(Valid, buffer+MAX_VALID_OFFSET, MAX_VALID_SIZE);//尾包数据有效值
				memcpy(&ValidData, Valid, sizeof(int32_t));
				memcpy(pData+hexIntNum*MAX_PACK_SIZE, buffer+MAX_DATA_OFFSET, ValidData);
				len += ValidData;
			}
			
			chkFileData[hexIntNum] = 1;
			i++;
			
			if (i == hexIntAllNum)
			{	
				if (ALLCHK1 == easy_hash_Crc32_GetResult(pData,len))
				{
					*ppFileData = pData;
					*pDataLen = len;
					ret = 0 ;
					free(chkFileData);
					close(sockfd);
					return ret;
				}
				else
				{			
					free(pData);
					free(chkFileData);
					close(sockfd);
					ret = -1;
					return ret;
				}
			}
		}
		else
		{
			continue;
	    }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值