C++多UDP socket数据处理
C++ multiple UDP socket data processing
我是 c++ 套接字编程的初学者,我遇到了一个问题,我尝试处理了一段时间。
我的任务是处理从两个不同传感器接收到的数据。我通过 UDP 套接字接收数据,然后处理数据包(显然所有这些都发生在 while 循环中)。我使用数据进行实时可视化,所以我需要整个过程快速。
只要我尝试从一个传感器接收数据,就一切正常。当我想使用两个传感器(因此在一个循环中使用两个 recvfrom() 函数)时,这就是我的问题开始的时候。处理速度非常慢,因此我错过了一些数据包。我知道 recvfrom() 函数是一个阻塞调用,我用 select() 函数处理了它,因此我知道这不是问题的根源。
下面是代码中似乎要引起大惊小怪的部分:
while (1)
{
SingleSocketReceiver(&socket_1, port_1, scene_1, ptrScene_1, model);
SingleSocketReceiver(&socket_2, port_2, scene_2, ptrScene_2, model);
}
当我评论第二个 SingleSocketReceiver() 函数时,一切正常。
这是 SingleSocketReceiver() 函数的组成部分:
int SingleSocketReceiver(UDPsocket* socket, uint16_t port,pcl::PointCloud<pcl::PointXYZ> scene, pcl::PointCloud<pcl::PointXYZ>::Ptr ptrScene, pcl::PointCloud<pcl::PointXYZ>::Ptr model)
{
struct timeval tv;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(socket->pSocket,&rfds);
tv.tv_sec = 1;
tv.tv_usec = 0;
if ((socket->rc = select(FD_SETSIZE,&rfds,NULL,NULL,&tv)) < 0)
{
printf("Port No. %d: ERROR! - no data received!\n", port);
return RESULT_ERROR;
}
else if (socket->rc == 0)
{
printf("Port No. %d: Timeout - no data received!\n", port);
return RESULT_ERROR;
}
socket->rc=recvfrom(socket->pSocket,(char*)socket->udpPacketBuf,UDP_PACKET_BUF_LEN,0,&socket->remoteAddr,&socket->remoteAddrLen);
if(socket->rc==SOCKET_ERROR)
{
printf("Socket for port No.%d: Error in recvfrom\n", port);
return RESULT_ERROR;
}
else
{
// Check the packet counter for missing packets
if (socket->previous_packet_counter_valid)
{
if ((socket->ph->PacketCounter - socket->previous_packet_counter) != 1)
{
printf("Port No.%d: Packet Counter jumped from %u to %u (missing packets; try to redirect output)\n", port, socket->previous_packet_counter, socket->ph->PacketCounter);
socket->startOfChannelFound = 0;
}
}
socket->previous_packet_counter = socket->ph->PacketCounter;
socket->previous_packet_counter_valid = 1;
// is this the channel with our data?
if (socket->ph->ChannelID == socket->customerDataChannel)
{
if (socket->ph->IndexOfPacketInChannel == 0)
{
socket->startOfChannelFound = 1;
if (socket->channel_buf_size == 0)
{
socket->channel_buf_size = socket->ph->TotalLengthOfChannel;
socket->channelBuf = (int8_t*) malloc(socket->channel_buf_size);
}
// as we reuse the buffer we clear it at the beginning of a transmission
memset(socket->channelBuf, 0, socket->channel_buf_size);
socket->pos_in_channel = 0;
}
if (socket->startOfChannelFound)
{
processPacket(socket->udpPacketBuf, socket->rc, socket->channelBuf, socket->channel_buf_size, &socket->pos_in_channel);
if (socket->ph->IndexOfPacketInChannel == socket->ph->NumberOfPacketsInChannel -1)
{
processChannel8(socket->channelBuf, socket->pos_in_channel);
displayData();
createPointCloud(scene, ptrScene, model);
}
}
}
}
return RESULT_OK;
}
如果有人提出真正的问题可能是什么以及处理它的可能方法是什么,我将不胜感激。不幸的是,我无法向您展示我的全部源代码,因为我是为了我的工作而这样做的,而且我不允许公开展示它。
请原谅我在这方面的知识不足。我愿意回答所有其他问题。
不要分别为每个套接字调用 select()。使用两个套接字设置一个select,然后处理可用数据(来自一个或两个套接字)。
select
可以处理多个套接字,所以使用这种方式。在单个循环中执行多个 recvfrom
是错误的。而是使用 select 找出您在哪个套接字上有数据,并从 remoteaddr 参数找出这些数据的来源。
我是 c++ 套接字编程的初学者,我遇到了一个问题,我尝试处理了一段时间。
我的任务是处理从两个不同传感器接收到的数据。我通过 UDP 套接字接收数据,然后处理数据包(显然所有这些都发生在 while 循环中)。我使用数据进行实时可视化,所以我需要整个过程快速。
只要我尝试从一个传感器接收数据,就一切正常。当我想使用两个传感器(因此在一个循环中使用两个 recvfrom() 函数)时,这就是我的问题开始的时候。处理速度非常慢,因此我错过了一些数据包。我知道 recvfrom() 函数是一个阻塞调用,我用 select() 函数处理了它,因此我知道这不是问题的根源。
下面是代码中似乎要引起大惊小怪的部分:
while (1)
{
SingleSocketReceiver(&socket_1, port_1, scene_1, ptrScene_1, model);
SingleSocketReceiver(&socket_2, port_2, scene_2, ptrScene_2, model);
}
当我评论第二个 SingleSocketReceiver() 函数时,一切正常。
这是 SingleSocketReceiver() 函数的组成部分:
int SingleSocketReceiver(UDPsocket* socket, uint16_t port,pcl::PointCloud<pcl::PointXYZ> scene, pcl::PointCloud<pcl::PointXYZ>::Ptr ptrScene, pcl::PointCloud<pcl::PointXYZ>::Ptr model)
{
struct timeval tv;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(socket->pSocket,&rfds);
tv.tv_sec = 1;
tv.tv_usec = 0;
if ((socket->rc = select(FD_SETSIZE,&rfds,NULL,NULL,&tv)) < 0)
{
printf("Port No. %d: ERROR! - no data received!\n", port);
return RESULT_ERROR;
}
else if (socket->rc == 0)
{
printf("Port No. %d: Timeout - no data received!\n", port);
return RESULT_ERROR;
}
socket->rc=recvfrom(socket->pSocket,(char*)socket->udpPacketBuf,UDP_PACKET_BUF_LEN,0,&socket->remoteAddr,&socket->remoteAddrLen);
if(socket->rc==SOCKET_ERROR)
{
printf("Socket for port No.%d: Error in recvfrom\n", port);
return RESULT_ERROR;
}
else
{
// Check the packet counter for missing packets
if (socket->previous_packet_counter_valid)
{
if ((socket->ph->PacketCounter - socket->previous_packet_counter) != 1)
{
printf("Port No.%d: Packet Counter jumped from %u to %u (missing packets; try to redirect output)\n", port, socket->previous_packet_counter, socket->ph->PacketCounter);
socket->startOfChannelFound = 0;
}
}
socket->previous_packet_counter = socket->ph->PacketCounter;
socket->previous_packet_counter_valid = 1;
// is this the channel with our data?
if (socket->ph->ChannelID == socket->customerDataChannel)
{
if (socket->ph->IndexOfPacketInChannel == 0)
{
socket->startOfChannelFound = 1;
if (socket->channel_buf_size == 0)
{
socket->channel_buf_size = socket->ph->TotalLengthOfChannel;
socket->channelBuf = (int8_t*) malloc(socket->channel_buf_size);
}
// as we reuse the buffer we clear it at the beginning of a transmission
memset(socket->channelBuf, 0, socket->channel_buf_size);
socket->pos_in_channel = 0;
}
if (socket->startOfChannelFound)
{
processPacket(socket->udpPacketBuf, socket->rc, socket->channelBuf, socket->channel_buf_size, &socket->pos_in_channel);
if (socket->ph->IndexOfPacketInChannel == socket->ph->NumberOfPacketsInChannel -1)
{
processChannel8(socket->channelBuf, socket->pos_in_channel);
displayData();
createPointCloud(scene, ptrScene, model);
}
}
}
}
return RESULT_OK;
}
如果有人提出真正的问题可能是什么以及处理它的可能方法是什么,我将不胜感激。不幸的是,我无法向您展示我的全部源代码,因为我是为了我的工作而这样做的,而且我不允许公开展示它。
请原谅我在这方面的知识不足。我愿意回答所有其他问题。
不要分别为每个套接字调用 select()。使用两个套接字设置一个select,然后处理可用数据(来自一个或两个套接字)。
select
可以处理多个套接字,所以使用这种方式。在单个循环中执行多个 recvfrom
是错误的。而是使用 select 找出您在哪个套接字上有数据,并从 remoteaddr 参数找出这些数据的来源。