2016-09-28 2 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 매개 변수에서이 데이터의 출처를 찾으십시오.