Проблема решена - см. Примечания к решению внизу
Я пытаюсь создать простое приложение для тестирования микроконтроллера с поддержкой 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, чтобы уменьшить путаницу .....)
Теперь я получаюошибка при попытке отправить:
The attempted operation is not supported for the type of object referenced
Я бы дал своему первенцу информативное сообщение об ошибке на этом этапе!Ошибка постоянна независимо от того, какой целевой порт я использую.Единственное, о чем я могу думать, это то, что мне нужно где-то установить исходный порт, но я не вижу, как вы можете сделать это в любой из boost::asio
документации.
Окончательное разрешение
Мне удалось сделать эту работу, поэтому я собираюсь опубликовать ошибки, которые я нашел в хорошем аккуратном списке для всех, кто сталкивается с этим ответом и сталкивается со схожими проблемами со мной.Я думаю, что главная проблема, с которой я столкнулся, заключалась в том, что ни один из примеров наддува никогда не показывал, как подключиться к указанному IP, все они используют распознаватель.Это усложнило мне понимание примеров.
- При использовании вызова
from_string
для преобразования текстового IP-адреса используйте синтаксис из первого ответа ниже, а не мой синтаксис выше! При настройке сокета UDP, порядок операций имеет решающее значение! Если вы не хотите делать это в конструкторе, вам необходимо:
- Откройте сокет, используя требуемый протокол.
- Свяжите сокет с локальной конечной точкой, в которой указан источник Номер порта UDP.
- Подключите сокет к удаленной конечной точке, котораяуказывает пункт назначения IP и номер порта.
Попытка привязки после подключения приведет к сбою привязки.Передача будет работать нормально, но ваши пакеты будут отправлены с произвольного номера порта.
- Используйте метод send для фактической передачи. Не пытайтесь включить данные отладки с помощью
boost::asio::socket_base::debug(true)
! Все, что этот флаг, похоже, делает, это вызывает сообщения об ошибках во время другой функциональной отправки!
Я также хотел бы поделитьсячто самым ценным инструментом отладки во всем этом упражнении был Wireshark.Может быть, это только потому, что я привык иметь CRO или Protocol Analyzer, когда я работаю над подобными коммуникациями, но я обнаружил, что возможность видеть отображение байтов на проводе помогло мне разобраться с целой кучей вещей, которые яв противном случае никогда бы не выследил.
Приветствую вас за помощь в вопросах IP и помогаю мне понять разницу между connect и bind.