2016-09-28 220 views
0

我是一個初學者在c + +套接字編程,我有一個問題,我試圖處理一段時間。C++多UDP套接字數據處理

我的任務是處理來自兩個不同傳感器的數據。我通過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; 

}

我會,如果有人認爲真正的問題可能是什麼非常感激和處理它的可能方式是什麼?不幸的是,我無法向您展示我的整個源代碼,因爲我爲我的工作做了這些工作,而且我不允許公開展示它。

請原諒我缺乏這方面的知識。我願意回答所有其他問題。

回答

1

不要分別爲每個套接字調用select()。使用兩個套接字設置選擇,然後處理可用數據(來自一個或兩個套接字)。

+0

非常感謝你!這有助於:) – nanasable

0

select可以處理多個套接字,所以使用這種方式。在單個循環中執行多個recvfrom是錯誤的。而是使用select來找出哪些套接字有數據,並從remoteaddr參數中找出這些數據來自哪裏。