c++多UDP套接字数据处理

C++ multiple UDP socket data processing

本文关键字:数据处理 套接字 UDP c++      更新时间:2023-10-16

我是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 recvfromn", 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参数中查找这些数据来自何处。