nanasable
nanasable

Reputation: 3

C++ multiple UDP socket data processing

I'm a beginner in c++ socket programming and I have a problem that I'm trying to handle for some time.

My task is to process data received from two different sensors. I receive the data through UDP socket and then process the packet (obviously all of that happens in a while loop). I use the data to real time visualisation so I need the whole process to be quick.

Everything is all right as long as I try to receive data from one sensor. When I want to do it with two sensors (and hence with two recvfrom() functions in one loop), here is when my problems begin. The processing is really slow and consequently I miss some packets. I'm aware of the fact that the recvfrom() function is a blocking call and I handled it with select() function, thus I know it's not the source of the problem.

Here is the part of the code that seems to be responsible for the fuss:

 while (1)
{
    SingleSocketReceiver(&socket_1, port_1, scene_1, ptrScene_1, model);
    SingleSocketReceiver(&socket_2, port_2, scene_2, ptrScene_2, model);
 }

When I comment the second SingleSocketReceiver() function, everything works fine.

And here is what the SingleSocketReceiver() function comprises:

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;

}

I would be extremely grateful if someone suggest what the real problem might be and what are the possible ways of handling it. Unfortunately, I cannot show you my whole source code as I do it for my work and I am not allowed to present it publicly.

Please forgive me my lack of knowledge in this field. I'd willingly answer all of the additional questions.

Upvotes: 0

Views: 1336

Answers (2)

rakib_
rakib_

Reputation: 142625

select can handle multiple sockets, so use such way. Doing multiple recvfrom on a single loop is wrong. Rather use select to find out on which socket you have data and from remoteaddr parameter find out from where these data are coming from.

Upvotes: 0

Rene
Rene

Reputation: 2474

Don't call select() for each socket separately. Set up a select with both sockets, and then process the available data (from one or two of the sockets).

Upvotes: 1

Related Questions