boost:asio IPv4-адрес и UDP-связь

Проблема решена — примечания к решению см. внизу

Я пытаюсь создать простое приложение для тестирования микроконтроллера с поддержкой Ethernet. Все, что я хочу сделать, это отправлять и получать небольшие пакеты UDP.Код использует boost::asio для работы в сети и невероятно прост. Для отладки я переместил всю инициализацию из конструкторов, чтобы иметь возможность проверять каждый шаг. Вот основная часть моего материала:

    boost::system::error_code myError;

    boost::asio::ip::address_v4 targetIP;
    targetIP.from_string("10.1.1.75", myError);                 // Configure output IP address. HACKHACK--Hardcoded for Debugging
    std::cout << "GetIP - " << myError.message() << std::endl;
    std::cout << "IP: " << targetIP << std::endl;

    boost::asio::ip::udp::endpoint myEndpoint;                  // Create endpoint on specified IP.
    myEndpoint.address(targetIP);
    myEndpoint.port(0x1000);
    std::cout << "Endpoint IP:   " << myEndpoint.address().to_string() << std::endl;
    std::cout << "Endpoint Port: " << myEndpoint.port() << std::endl;

    boost::asio::io_service io_service;                         // Create socket and IO service, bind socket to endpoint.
    udp::socket socket(io_service);
    socket.open( myEndpoint.protocol(), myError );
    std::cout << "Open - " << myError.message() << std::endl;
    socket.bind( myEndpoint, myError );
    std::cout << "Bind - " << myError.message() << std::endl;

    char myMessage[] = "UDP Hello World!";                      // Send basig string, enable socket level debugging.
    socket.send(boost::asio::buffer(myMessage, sizeof(myMessage)), boost::asio::socket_base::debug(true), myError);
    std::cout << "Send - " << myError.message() << std::endl;

    boost::array<char, 128> recv_buf;                           // Receive something (hopefully an echo from the uP)
    udp::endpoint sender_endpoint;
    size_t len = socket.receive_from( boost::asio::buffer(recv_buf), myEndpoint );
    std::cout.write(recv_buf.data(), len);

Загвоздка возникает в самом начале. Address_v4 не хочет принимать IP-адрес, который я ему передаю. Вывод этого приложения:

GetIP - The operation completed successfully
IP: 0.0.0.0
Endpoint IP:   0.0.0.0
Endpoint Port: 4096
Open - The operation completed successfully
Bind - The operation completed successfully
Send - A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied

Я предполагаю, что ошибка отправки является результатом неправильной установки address_v4, но я не могу придумать причину, чтобы такая вещь была происходит.

Для тех, кто играет дома, скажу, что на моем ПК установлены две сетевые карты, одна из которых настроена на DHCP 10.1.1.7, поэтому целевой IP-адрес должен быть доступен без какой-либо маршрутизации. Я использую BOOST 1.46.1 на 32-разрядной Win7 и MSVS 10. Он также не работает, когда я пытаюсь ввести IP-адрес 127.0.0.1, поправьте меня, если я ошибаюсь, но это должно работать для обратной связи в этот контекст?

Изменить с обновлениями:

Итак, благодаря более ранним ответам, я получил IP-адрес в свой address_v4и больше не пытаюсь выполнять привязку, когда хотел использовать соединение. Значительно измененный раздел кода — это TX, который теперь выглядит так:

    socket.open( targetEndpoint.protocol(), myError );
    std::cout << "Open - " << myError.message() << std::endl;
    char myMessage[] = "UDP Hello World!";                      // Send basig string, enable socket level debugging.
    socket.send_to(boost::asio::buffer(myMessage, sizeof(myMessage)), targetEndpoint, boost::asio::socket_base::debug(true), myError);
    std::cout << "Send - " << myError.message() << std::endl;

(я переименовал myEndpoint в targetEndpoint, чтобы уменьшить путаницу.....)

Теперь я получаю сообщение об ошибке при попытке отправить:
Попытка операции не поддерживается для типа объекта, на который ссылаются
Я бы отдал своего первенца за информативное сообщение об ошибке на этом этапе! Ошибка постоянна независимо от того, какой целевой порт я использую.Единственное, что я могу придумать, это то, что мне нужно где-то установить исходный порт, но я не вижу, как это можно сделать ни в одной из документации boost::asio.

Окончательное решение

Мне удалось заставить эту работу работать, поэтому я собираюсь опубликовать найденные мной ошибки в красивом аккуратном списке для всех, кто наткнется на этот ответ с проблемами, похожими на меня. Я думаю, что основная проблема, с которой я столкнулся, заключалась в том, что ни один из примеров повышения никогда не показывает, как подключиться к указанному IP-адресу, все они используют преобразователь. Это сделало примеры намного труднее для понимания для меня.

  • При использовании вызова from_stringдля преобразования текстового IP-адреса используйте синтаксис из первого ответа ниже, а не мой синтаксис выше!
  • При настройке UDP-сокета порядок операций имеет решающее значение! Если вы не хотите делать это в конструкторе, вам необходимо:

    1. Открыть сокет по нужному протоколу.
    2. Привяжите сокет к локальной конечной точке, в которой указан номер источникаUDP.
    3. Подключите сокет к удаленной конечной точке, которая указывает IP-адрес и номер порта назначения.

    Попытка выполнить привязку после подключения приведет к сбою привязки. Передача будет работать нормально, но ваши пакеты будут отправляться с произвольного номера порта.

  • Используйте метод отправки для фактической передачи.Не пытайтесь включить данные отладки с помощью boost::asio::socket_base::debug(true)! Кажется, что все, что делает этот флаг, — это вызывает сообщения об ошибках при отправке, которая в остальном работает!

Я также хотел бы поделиться тем, что моим самым ценным инструментом отладки во всем этом упражнении был Wireshark. Может быть, это только потому, что я привык иметь CRO или анализатор протокола, когда я работаю с такими сообщениями, но я обнаружил, что возможность видеть отображение байтов на проводе помогло мне разобраться с целой кучей вещей, которые я иначе никогда бы не выследил.

Благодарю вас за помощь в вопросах IP и за то, что помогли мне понять разницу между подключением и привязкой.

8
задан mattytommo 19 March 2013 в 14:30
поделиться