2012-03-27 1 views
7

Проблема решена - см снизу для решения отмечаетповышение: ASIO IPv4-адрес и UDP порта связи

Я пытаюсь создать простое приложение для тестирования локальных сетей с поддержкой микроконтроллера. Все, что я хочу сделать, это отправлять и получать небольшие 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); 

Защелка происходит в самом начале. Адрес_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 не получает набор правильно, но нет никаких оснований, что я могу думать такую ​​вещь, чтобы иметь место ,

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

Редактировать с Updates:

Так благодаря более ранним ответам я уже получил IP-адрес в мои address_v4, и я больше не пытаюсь связать, когда я имел в виду использовать соединение. Significanly измененная часть кода является 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, чтобы помочь уменьшить путаницу .....)

теперь я получаю сообщение об ошибке при попытке отправьте:
The attempted operation is not supported for the type of object referenced
Я дам свой первенец для информативного сообщения об ошибке на этом этапе! Ошибка согласована независимо от того, какой целевой порт я использую. Единственное, о чем я могу думать, это то, что мне нужно установить порт источника где-нибудь, но я не вижу, как вы можете это сделать в любой из документации boost::asio.

Final Resolution

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

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

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

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

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

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

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

+0

OK, дальнейшая информация: Если я использую 'boost :: asio :: ip :: address_v4 :: bytes_type' для представления IP, я могу успешно передать любой IP-адрес по своему выбору. Я также могу построить конечную точку с 'boost :: asio :: ip :: address_v4 :: loopback()' в качестве аргумента и оценивает IP-адрес 127.0.0.1. К сожалению, это не изменяет более позднюю ошибку при отправке, когда я запускаю любую из этих настроек ... – OcularProgrammer

+0

Редактировать свой вопрос с помощью этой информации, это не должно быть комментарий –

ответ

6

Проблема вы сейчас видите, кажется, ваше использование этой линии:

targetIP.from_string("10.1.1.75", myError); 

boost::asio::ip::address::from_string статическая функция, который возвращает построенный объект ip::address. Измените это так:

targetIP = boost::asio::ip::address::from_string("10.1.1.75", myError); 

И ваш IP-адрес должен быть заполнен должным образом.

+0

Cheers Chad, я до сих пор довольно новичок в C++, мой фон C на микроконтроллерах.Я должен научиться следить за магическими словами, такими как «статические» в режиме ожидания. Это исправление успешно получает мой IP-набор, если я использую 'boost :: asio :: ip :: address_v4 :: from_string (" xxx ")'. По-прежнему возникают проблемы с отправкой данных, но по крайней мере теперь я могу воспринимать IP разумным образом. – OcularProgrammer

0

Сверху моей головы вы пытаетесь привязать сокет к конечной точке с адресом 10.1.1.75, но это, кажется, удаленная конечная точка? Я предполагаю, что вы хотели бы, чтобы связать его локально и использовать send_to, как это UDP

+0

Приветствия за этот Ролл, я получил 'bind' и' connect' запутались. У меня создалось впечатление, что boost все равно будет socket.connect с UDP для кодирования конечной точки цели в объекте сокета, но я перешел на использование send_to только для того, чтобы быть в безопасности. К сожалению, теперь я получаю сообщение «При попытке и отправке попытка попытки операции не поддерживается для типа объекта, на который делается ссылка». Есть идеи по этому поводу? – OcularProgrammer

0

В этой строке есть ошибка:

targetIP = boost::asio::ip::address::from_string("10.1.1.75", myError); 

Вы должны поставить:

targetIP = boost::asio::ip::address_v4::from_string("10.1.1.75", myError); 

, а затем targetIP имеет правильное значение!

Смежные вопросы