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;
}
}
}