CANOE CAPL 实现以太网报文发送和接收
概述
上一片主要讲解以太网的发送,以及如何以HEX形式发送
这一篇主要讲解如何实现多端口发送,多端口接收报文,以及处理报文。
一、
variables
{
UdpSocket gSocket1;//交流17681826077
UdpSocket gSocket2;//55001 端口
UdpSocket gSocket3;//30001端口
}
宗旨:一个工程里可以创建多个Socket,然后用端口绑定
on start
{
gSocket1= UdpSocket::Open( IP_Endpoint(0.0.0.0:30490) );
gSocket2 = UdpSocket::Open( IP_Endpoint(0.0.0.0:55000) );
gSocket3 = UdpSocket::Open( IP_Endpoint(0.0.0.0:30001) );
if (IpGetLastError() != 0)
{
write( “<%BASE_FILE_NAME%> UdpSocket::Open failed with result %d”, IpGetLastError() );
}
gSocket2.ReceiveFrom( gRxBuffer, elcount(gRxBuffer) ); //对端口55000接收的数据做处理,为后面接收函数做准备
}
on preStop
{
// Close socket on measurement stop
gSocket.Close();
}
以下这个函数是ASCLL转16进制关键函数
byte GBF_ConvertHexStrToByteArray(char hexRawData[], byte outByteArr[])// ASCLL转16进制关键函数
{
word i;
word offset;
word hexLength;
byte tmpVal;
byte retVal;
char tmpErrStr[200];
byte outdword;
const byte dataType = 2;
byte gcNok = 0;
byte gcOk = 1;
// Init to failed
retVal = gcNok;
offset = 0;
// Reset output
outdword = 0;
// get the hex length
hexLength = strlen(hexRawData);
//remove possible “0x” at the beginning
if( hexRawData[0] == ‘0’ && hexRawData[1] == ‘x’ )
offset = 2;
/*(/check that the a dword (4 bytes) can hold the hex string
if ( dataType < (hexLength - offset)/2 )
{
snprintf(tmpErrStr, elcount (tmpErrStr), “GBF_ConvertHexStrToInt: ERROR: Hex Data is %d which is more than a dword can hold!”, hexLength);
write (“Error in GBF_ConvertHexStrToInt: string is: %s”,hexRawData);
write(tmpErrStr);
}
else
{ */
retVal = gcOk;
//All checks went fine, convert data
for (i = offset; i < hexLength; i++)
{
outdword = outdword << 4; //shift the result
// convert the Hex data and validity check it
tmpVal = (byte)hexRawData[i];
if (tmpVal >= 0x30 && tmpVal <= 0x39) //0-9
tmpVal = tmpVal - 0x30;
else if(tmpVal >= ‘A’ && tmpVal <= ‘F’) //A-F
tmpVal = tmpVal - 0x37;
else if (tmpVal >= ‘a’ && tmpVal <= ‘f’) //a-f
tmpVal = tmpVal - 0x57;
else
{
snprintf(tmpErrStr, elcount (tmpErrStr), “GBF_ConvertHexStrToInt: ERROR: Invalid Hex data found in Hex string at position %d”, i);
// write(tmpErrStr);
retVal = gcNok;
break;
}
outdword = outdword | tmpVal; //one nibble at a time…
if(i%dataType == dataType-1)
outByteArr[i/dataType] = outdword;
}
return retVal;
}//ASCLL转16进制关键函数
这个函数参见:https://blog.csdn.net/qq_34414530/article/details/107916856
void OnUdpReceiveFrom( dword socket, long result, ip_Endpoint remoteEndpoint, byte buffer[], dword size)//最为关键的接收函数,此为回调函数
{
if (result == 0)
{
char endpointString[30];
remoteEndpoint.PrintEndpointToString( endpointString );
}
if(buffer[0]==0x2&buffer[1]==0x1&buffer[2]==0x80&buffer[3]==0x1)//对接收的数据做判断,
{
sysSetVariableInt( sysvar::huts::a,buffer[32] );//对接收的数据做处理
sysSetVariableInt( sysvar::huts::b,buffer[33] );//对接收的数据做处理
}
gSocket2.ReceiveFrom( gRxBuffer, elcount(gRxBuffer) );
}