Попытка установить связь UDP между двумя ноутбуками с Ubuntu с помощью стандартных команд сокетов - PullRequest
0 голосов
/ 11 июля 2019

Я пытаюсь установить связь между двумя компьютерами с помощью команд сокета UDP. Ниже приведен код. Я проверил этот код, запустив на одном и том же устройстве два отдельных терминала. Прием может принимать пакеты, если передатчик находится на одном и том же устройстве, но функция recv не может перехватывать пакеты, если пакеты поступают с другого устройства. Я могу перехватить или увидеть пакеты в tcpdump. Настроить: Два компьютера с IP 10.66.106.161 и 10.66.106.115

Я вставил код и изображение tcpdump. Пожалуйста, дайте мне знать, где я поступил неправильно, столкнулся с этой конкретной проблемой за последние две недели.

Сначала я просто попытался установить связь с любым базовым IP-адресом, а затем получил код ошибки 14: Bad Address. Поэтому я изменил IP-адрес с IP-адресом источника, но все равно получаю ту же ошибку.

   int32_t UdpHelper::OpenRxSocket(std::string local_port_as_str, 
   std::string source_IP)
   {

int convert = inet_pton(AF_INET, source_IP.c_str(), &m_remoteAddrRx); //convert string IP to binary and store in m_remoteAddrRx
if(convert)
{
    printf("Conversion success.\n");
}
m_remoteAddrRxLen = sizeof(m_remoteAddrRx);
struct addrinfo addrInfoHints, *servinfo, *pAddrInfo;

memset(&addrInfoHints, 0, sizeof(addrInfoHints));
addrInfoHints.ai_family = AF_INET; // force IPv4
addrInfoHints.ai_socktype = SOCK_DGRAM;
addrInfoHints.ai_flags = AI_PASSIVE; // use my IP

FD_ZERO(&m_readFds); // clear set of file descriptors

int tempval = getaddrinfo(
    NULL,
    local_port_as_str.c_str(),
    &addrInfoHints,
    &servinfo);
if (0 != tempval)
{
    printf("UdpHelper - OpenRxSocket: %s\n", gai_strerror(tempval));
    return -1;
}

// loop through results and try to bind the first possible
for (pAddrInfo = servinfo; pAddrInfo != NULL; pAddrInfo = pAddrInfo->ai_next)
{

    if ((m_socketRx = socket(pAddrInfo->ai_family, pAddrInfo->ai_socktype, pAddrInfo->ai_protocol)) == -1)
    {
        continue;
    }

    // hide "already in use" message
    int yes = 1;
    setsockopt(m_socketRx, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

    // set timeoutservinfo
    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 2000;
    setsockopt(m_socketRx, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof(tv));

    if (-1 == bind(m_socketRx, pAddrInfo->ai_addr, pAddrInfo->ai_addrlen))
    {
        close(m_socketRx);
        continue;
    }
    else
    {
        printf("UdpHelper - OpenRxSocket: Binding Succes.\n");
    }

    break;
}

if (NULL == pAddrInfo)
{
    printf("UdpHelper - OpenRxSocket: Failed to bind RX socket.\n");
    return -1;
}

freeaddrinfo(servinfo);

FD_SET(m_socketRx, &m_readFds); // add socket file descriptor to the list
m_fdMax = m_socketRx + 1;       // keep track of the biggest file descriptor

//printf("UdpHelper - OpenRxSocket: All done. socket=%i\n", m_socketRx);

/*  int listenfd, len; 
struct sockaddr_in servaddr, cliaddr; 
bzero(&servaddr, sizeof(servaddr)); 

// Create a UDP Socket 
m_socketRx = socket(AF_INET, SOCK_DGRAM, 0);         
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
servaddr.sin_port = htons(5208); 
servaddr.sin_family = AF_INET;  

// bind server address to socket descriptor 
if ( -1 == bind(m_socketRx, (struct sockaddr*)&servaddr, sizeof(servaddr)))
{
    close(m_socketRx);
    printf( "UdpHelper - OpenRxSocket: Failed to bind RX socket.\n" );
} 
else
{
    printf( "UdpHelper - OpenRxSocket: Binding Succes.\n" );
} */

return 0;
    }

    void UdpHelper::SocketRecvU8(
uint8_t *p_buffer_U8,
uint16_t length)
    {
int32_t numBytesRx = 0;
// uint32_t bufU8RxEntry = 0;

// the descriptor has data
if (FD_ISSET(m_socketRx, &m_readFds))
{
    numBytesRx = recvfrom(m_socketRx, p_buffer_U8,
                          length,0,
                          (struct sockaddr *)&m_remoteAddrRx,
                          &m_remoteAddrRxLen);
    // numBytesRx = recv (m_socketRx, p_buffer_U8,
    //      length, 0);
    if (numBytesRx > 0)
    {
        std::cout << "Udp packet of size " << numBytesRx << " from ip addr=" << inet_ntoa(((struct sockaddr_in *)&m_remoteAddrRx)->sin_addr) << " received." << std::endl;
    }
    printf("UdpHelper numBytesRx=%i\n", numBytesRx);
    printf("errno=%i, %s\n", errno, strerror(errno));
    int recvBufSize;
    socklen_t *clientLen;
    int err = getsockopt(m_socketRx, SOL_SOCKET, SO_RCVBUF,
                         (char *)&recvBufSize, clientLen);
    std::cout << "UDP RX socket created and opened with"
              << " local socket = " << m_socketRx
              << " recvBufSize= " << recvBufSize
              << " err = " << err << std::endl;
              printf("errno=%i, %s\n", errno, strerror(errno));
}

}

Я ожидал, что пакеты будут получены. Когда на одном устройстве выполняются функции передачи и приема, я получаю пакеты. Ниже вывод.

Udp packet of size 20 from ip addr=127.0.0.1 received.
UdpHelper numBytesRx=20
errno=14, Bad address
UDP RX socket created and opened with local socket = 3 recvBufSize= 0 err = -1
errno=14, Bad address
0
...