Win32 UDP 单向接收

#include <Winsock2.h>
#include <stdio.h>
#include <iostream.h>
#include <time.h>
#include <math.h>
#define  RECVBUF_LEN    1500
#define  UDPPORT        60000
#define  FUNCODE_DIN    1
#define  FUNCODE_AIN    3
#define  FUNCODE_CLOCK  6
#define  FUNCODE_DITAG  8
#define  FUNCODE_AITAG  9


#define  POSITION_OF_LEN 2//lenth in message header
#define  POSITION_OF_NUM 5//num in body header
#define  POSITION_OF_DATA 9//data in body
#define  POSITION_OF_TYPE 4//data type in body
#define  NUMBER_OF_HEADER 4 //header of a complete message
#define  NUMBER_OF_MSGHEADER 5//header of body
#define  MAX_MESSAGE_LEN  1035

#define  NAMESIZE       20 //size of tag name

#define  ERRORMSG_LEN   1000
#define  MAXRRECNUM     1000


struct _RECVDATA{
 unsigned char DINValue;
 float AINValue;
 int type;//8-di;9-ai
 char TAG[NAMESIZE];
}gRecv_DIData[MAXRRECNUM],gRecv_AIData[MAXRRECNUM];


void           InitSocket();
void           CloseSocket();
void           exit_udp();
void           MsgRecv();
void           MsgProcess();
void           DINRead();
void           AINRead();
void           SGRead();
void           ClockRead();
void           TAGRead(_RECVDATA *recvdata);
bool           CheckSum(unsigned char *ptr);
unsigned short GetSum(unsigned char *ptr, int nbytes);
void           InitData();
void           TAGTransfer(char *tag,unsigned char *recvtag);

void           MyPrintf(char* des,BYTE * buf,int len);

 


BYTE           gRecvBuf[RECVBUF_LEN];
SOCKADDR_IN    gLocal_SockAddr,gRemote_SockAddr;
WSADATA        gWsadata;
WORD           gWord;
SOCKET         gSocket;
unsigned char  gStationAddr;
int            gAINCount;
int            gDINCount;
struct tm      *gTM;//receive time
int            gbodylen;//body lenth,total count = gbodylen + NUMBER_OF_HEADER + 2
char           gErrorMsg[ERRORMSG_LEN];
int            gRedFlag;//flag of main/backup


void main()
{
 InitSocket();
 InitData();

 while(1)
 {
  if(gRedFlag == 1) MsgRecv();
  else
  {
   sprintf(gErrorMsg,"I'M BACKUP,WAITING...");
   printf("%s\n",gErrorMsg);
  }
//     _sleep(100);
 }

 CloseSocket();
 
}//endof main()

 

 

void  InitData()

 gbodylen = 0;
 gStationAddr = 1;
 gRedFlag = 0;
}

void  InitSocket()
{

 gWord=MAKEWORD(1,1);
 int err;
 err=WSAStartup(gWord,&gWsadata);

 if(err!=0)
 {
  printf("link err!");
  exit_udp();
 }
 if(LOBYTE(gWsadata.wVersion)!=1 || HIBYTE(gWsadata.wVersion!=1))
 {
  printf("ver err");
  exit_udp();
 }
 //create socket
 gSocket = socket (AF_INET,SOCK_DGRAM, 0);
 if(gSocket<0){
  printf("ERR--Crerat socket error\n");
  exit_udp();
 }


 gLocal_SockAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
 gLocal_SockAddr.sin_family = AF_INET;
 gLocal_SockAddr.sin_port = htons(UDPPORT);
 if(bind(gSocket, (SOCKADDR *)&gLocal_SockAddr,sizeof(SOCKADDR))<0)
 {
  printf("ERR--bind error\n");
  exit_udp();
 }
}//end of init_sock

void  CloseSocket()
{
 closesocket(gSocket);
 WSACleanup();
}

void   MsgRecv()
{
 fd_set readfds;
 timeval timeout={5,0};//5s recv timeout
 int len=sizeof(SOCKADDR);
 int a = 0;
 int out=0;
 char tempbuf = '0';
 unsigned long total_lenth=0; 
 while(1){
   FD_ZERO(&readfds);
   FD_SET(gSocket,&readfds);
   out = select(0, &readfds, NULL, NULL, &timeout);//receive timeout judg
   ioctlsocket(gSocket,FIONREAD,&total_lenth);//get receive buffer's actual lenth
 
   if(out>0){//data coming
   memset(gRecvBuf,NULL,RECVBUF_LEN);//clear receive buffer
         a=recvfrom(gSocket,(char *)gRecvBuf,MAX_MESSAGE_LEN,0,(SOCKADDR*)&gRemote_SockAddr,&len);//receive header
   if(a == SOCKET_ERROR && WSAGetLastError()!=10040)
   {
   sprintf(gErrorMsg,"ERR----HEADER ERROR CODE:%d",WSAGetLastError());
   printf("%s\n",gErrorMsg);
   return;
   }
   else if(gRecvBuf[0] != 0x68)
   { 
   sprintf(gErrorMsg,"ERR----WRONG START BIT:%d",gRecvBuf[0]);
   printf("%s\n",gErrorMsg);
   return;
   }
   else if(gRecvBuf[1] != gStationAddr)
   {
   sprintf(gErrorMsg,"%s","ERR-----Wrong Station Address");
   printf("%s\n",gErrorMsg);
   return;
   }

   gbodylen = gRecvBuf[POSITION_OF_LEN] + gRecvBuf[POSITION_OF_LEN+1]*256;//body lenth in header
   if(gbodylen>RECVBUF_LEN)
   {  
      sprintf(gErrorMsg,"%s","ERR-----Not Enough Buffer");
   printf("%s\n",gErrorMsg);
   return;  
   }
       
   if(CheckSum(gRecvBuf))   MsgProcess();

   } //end of if(out>0)
   else
   {
    printf("%ds recv timeout\n",timeout.tv_sec);
   } 

 }//end_while
}

void  MsgProcess()
{

   switch(gRecvBuf[POSITION_OF_TYPE]){
   case FUNCODE_DIN:
         printf("recvDIN\n");
   DINRead();
    _sleep(20);
   break;
    case FUNCODE_AIN:
   printf("recvAIN\n");
    AINRead();
    _sleep(20);
     break;
    case FUNCODE_CLOCK:
   printf("recvClock\n");
    ClockRead();
   _sleep(5);
     break; 
  case FUNCODE_DITAG:
   printf("Recv DITag\n");
   TAGRead(&gRecv_DIData[0]);
    _sleep(50);
   break;
  case FUNCODE_AITAG:
   printf("Recv AITag\n");
   TAGRead(&gRecv_AIData[0]);
    _sleep(50);
   break;
    default:
    printf("ERR-----Recv unknown code of %d\n",gRecvBuf[POSITION_OF_TYPE]);
   return;
     break;
   }
}

void DINRead()
{
 unsigned char *p=NULL;
 int num = gRecvBuf[POSITION_OF_NUM]+gRecvBuf[POSITION_OF_NUM+1]*256;
 int i = 0;
 unsigned short addr = gRecvBuf[POSITION_OF_NUM+2]+gRecvBuf[POSITION_OF_NUM+3]*256; /*start number of data in each message
                                                   for one kind of data was split into several messages*/


 gDINCount = num + addr;

    p = &gRecvBuf[POSITION_OF_DATA];
 if(num+NUMBER_OF_MSGHEADER != gbodylen)//lenth conflict
    {
       sprintf(gErrorMsg,"%s","ERR-----Wrong DIN Message");
    printf("%s\n",gErrorMsg);
    return;
 }
 
 for(i=addr;i<num+addr;i++)
 {
  gRecv_DIData[i].DINValue = *p;
        printf("DIN[%d] = %d  tag = %s\n",i,gRecv_DIData[i].DINValue,gRecv_DIData[i].TAG);
  p++;
 }
}


void AINRead()
{
 unsigned char *p=NULL;
 int num =  gRecvBuf[POSITION_OF_NUM]+gRecvBuf[POSITION_OF_NUM+1]*256;
 int i = 0;
 unsigned short addr = gRecvBuf[POSITION_OF_NUM+2]+gRecvBuf[POSITION_OF_NUM+3]*256;

 gAINCount = num + addr * 4 ;//consider of multi-messages

    p = &gRecvBuf[POSITION_OF_DATA];
 if((unsigned short)(num*sizeof(float)+NUMBER_OF_MSGHEADER) != gbodylen)//lenth conflict
    {
       sprintf(gErrorMsg,"%s","ERR-----Wrong AIN Message");
    printf("%s\n",gErrorMsg);
    return;
 }
 
 for(i=addr;i<num+addr;i++)
 {
  memcpy(&gRecv_AIData[i].AINValue,p,sizeof(float));
  printf("AIN[%d] = %f  tag = %s\n",i,gRecv_AIData[i].AINValue,gRecv_AIData[i].TAG);
  p+=sizeof(float);
 }
}

void TAGRead(_RECVDATA *recvdata)
{
 int i = 0;
 unsigned char *p=NULL;
 unsigned short num = 0;
 unsigned char type = 0;
 unsigned short addr = gRecvBuf[POSITION_OF_NUM+2]+gRecvBuf[POSITION_OF_NUM+3]*256;

 type = gRecvBuf[POSITION_OF_TYPE];
 num = gRecvBuf[POSITION_OF_NUM]+gRecvBuf[POSITION_OF_NUM+1]*256;
 p = &gRecvBuf[POSITION_OF_DATA];

    gAINCount = num + addr * 4 ;

 printf("%d----num=%d---addr=%d---------\n",gAINCount,num,addr);

    if((unsigned short)(num*4+NUMBER_OF_MSGHEADER) != gbodylen)//lenth conflict
    {
    printf("%d-----%d------\n",num*4+NUMBER_OF_MSGHEADER,gbodylen);
       sprintf(gErrorMsg,"%s","ERR-----Wrong Tag Message");
    printf("%s\n",gErrorMsg);
    return;
 }

 memset(recvdata,NULL,sizeof(_RECVDATA)*MAXRRECNUM);//clear buffer before write

 for(i=addr;i<num+addr;i++)
 {    
        TAGTransfer(recvdata[i].TAG,p);
        recvdata[i].type = type;
  printf("TAG[%d] = %s\n",i,recvdata[i].TAG); 
  p+=4;
 }
}

void ClockRead()
{
 time_t tt=0;
 unsigned char *p=NULL;
    p = &gRecvBuf[5];
 memcpy(&tt,p,sizeof(time_t));
 gTM = localtime(&tt);
 printf("RecvTime: %s",ctime(&tt));
// printf("RecvTime= %d",gTM->tm_year);
}

unsigned short GetSum(unsigned char *ptr, int nbytes)
{
  int  i;
  unsigned short sum;
  sum = 0;
  for (i=0; i<nbytes; i++)   sum += ptr[i];
  return(sum);
}

bool CheckSum(unsigned char *ptr)
{
   int msglenth=0;
   unsigned short sum=0;
   msglenth = gRecvBuf[POSITION_OF_LEN]+(gRecvBuf[POSITION_OF_LEN+1]*256)+NUMBER_OF_HEADER;
      sum = GetSum(ptr,msglenth);
   if((sum%256 == gRecvBuf[msglenth]) && (sum/256 == gRecvBuf[msglenth+1]))
    return true;
   else
   {
    printf("CheckSum==>%x %x\n",sum%256,sum/256);
    return false;
   }
}

/*----------tagname:4 BYTES(6b.6b.3b.4b.13b)-----------------
------------translate tagname to char---------------*/
void TAGTransfer(char *tag,unsigned char *recvtag)
{   
 unsigned char temp,temp2;
 unsigned short temp3;

 temp3=0;
 temp=temp2=0;
   
 memset(tag,NULL,NAMESIZE);

 temp =(recvtag[0]>>2) & 0x3f;
 sprintf(tag,"%d",temp);

    temp = recvtag[0] & 0x03;
 temp2 = recvtag[1] & 0xf0;
 temp =( temp <<4 ) | (temp2 >>4) & 0x3f;
    sprintf(tag,"%s.%d",tag,temp);

 temp = (recvtag[1]>>1) & 0x07;
    sprintf(tag,"%s.%d",tag,temp);

 temp = recvtag[1] & 0x01;
 temp2 = (recvtag[2]>>5) & 0x1f;
 temp = (temp<<3) | temp2 & 0x0f;
    sprintf(tag,"%s.%d",tag,temp);

 temp3 = (recvtag[2] & 0x1f)<<8 | recvtag[3];
 sprintf(tag,"%s.%d.",tag,temp3);

// printf("%x %x %x %x -- tag -- %s\n",recvtag[0],recvtag[1],recvtag[2],recvtag[3],tag);
}

void exit_udp()
{
 CloseSocket();
 exit(0);
}

 

void MyPrintf(char* des,BYTE * buf,int len)
{
 printf("%s,len=%d------>",des,len);
 for(int i=0;i<len;i++)
 {
  printf(" %x",buf[i]);
 }
 printf("\n");
}

 

### 回答1: 当使用STM32进行UDP(User Datagram Protocol,用户数据报协议)连续接收大量数据时,我们需要采取以下步骤: 1. 配置网络模块:首先,我们需要确保STM32芯片上的网络模块已经正确配置。这涉及到设置网络模块的工作模式、IP地址、端口号等。 2. 初始化UDP:接下来,需要初始化UDP协议栈。这包括设置套接字(socket)参数、绑定端口等。通过套接字可以实现数据的发送和接收。 3. 接收数据:一旦网络模块和UDP协议栈初始化完成,我们可以开始接收数据。使用套接字接收缓冲区从网络中接收数据包。 4. 数据处理:接收到的数据包通常需要进行一些处理,例如解析数据包中的信息、校验数据的完整性等。可以使用一些库或者自定义的函数来实现数据处理过程。 5. 存储数据:接收到的数据可以通过内部Flash、外部存储器或者其他设备进行长期存储。这也取决于您的具体应用需求。 6. 数据流控制:如果连续接收大量数据,可能需要考虑数据流控制。这可以通过使用带有缓冲区的环形队列或者设置适当的延时等方式来实现。 7. 错误处理:在接收数据的过程中,可能会发生一些错误,例如数据包丢失、传输错误等。因此,我们需要实现适当的错误处理机制,以确保数据的可靠性。 8. 优化性能:为了实现更好的性能,您可以采取一些优化措施,如使用DMA(Direct Memory Access,直接内存访问)技术来传输数据,提高数据传输速率。 总之,通过正确配置网络模块、初始化UDP协议栈、接收数据、处理数据、存储数据、流控制、错误处理和性能优化,您可以在STM32上实现连续接收大量数据的功能。具体的实现细节可能因具体应用需求而有所不同。 ### 回答2: 在STM32上进行UDP连续接收大量数据,需要先对UDP通信进行配置。 首先,需要初始化网络相关的硬件和软件资源,包括网卡和网络协议栈。接着,需要进行网络参数的配置,如IP地址和端口号等。这些可以通过STM32的外设库函数或者直接编写驱动程序来完成。 与此同时,设置好接收缓冲区的大小,以满足大量数据的接收需求,并确保接收缓冲区的大小与发送端发送的数据包大小匹配。接收缓冲区可以使用STM32的内存空间或外部存储设备来实现。 在接收数据的主程序中,可以使用STM32的中断机制或轮询方式来接收UDP数据包。若使用中断机制,需要通过外设库函数或者中断服务函数来触发中断并处理接收到的数据。若使用轮询方式,需要使用外设库函数或底层驱动程序在主循环中不断地接收数据。 为确保数据的完整性和正确性,可以计算UDP数据包的校验和,并在接收端进行验证。若校验和不匹配,则表明数据包可能被篡改,需要进行相应的处理。 在接收到大量数据后,可以根据实际需求进行数据处理和存储。可以将数据存储在内存中进行实时处理,或者将数据保存在外部存储设备中,以备后续分析和使用。 综上所述,通过正确的配置和编程,STM32可以实现UDP的连续接收大量数据的功能。需要注意的是,根据具体的应用场景和需求,可能需要进行进一步的优化和调试,以确保系统的稳定和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值