boost:asio IPv4地址和UDP通信

时间:2012-03-27 02:24:00

标签: c++ windows network-programming boost-asio

解决了问题 - 请参阅解答说明的底部

我正在尝试构建一个简单的应用来测试支持以太网的微控制器。我想要做的就是发送和接收小的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'd 10.1.1.7,所以目标IP应该可以在没有任何路由的情况下到达。我在32位Win7和MSVS 10上使用BOOST 1.46.1。当我尝试127.0.0.1的IP时它也失败了,如果我错了,请纠正我,但是在这种情况下这应该适用于环回? / p>

使用更新进行修改:

所以感谢早期的答案,我已经将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套接字时,操作顺序至关重要!如果您不想在构造函数中执行此操作,则需要:

    1. 使用所需协议打开套接字。
    2. 将套接字绑定到指定 UDP端口号的本地端点。
    3. 将套接字连接到指定目标 IP和端口号的远程端点。
    4. 尝试在连接后绑定将导致绑定失败。传输将正常运行,但您的数据包将从任意端口号发送。

    5. 使用send方法实际传输。 不要尝试使用boost::asio::socket_base::debug(true)启用调试数据!所有这个标志似乎都会导致其他函数发送错误消息!

我还想分享一下,在整个练习中我最有价值的调试工具是Wireshark。也许这只是因为我习惯使用CRO或协议分析器来处理这样的通信时,但是我发现能够看到线上字节显示有助于我整理掉一大堆东西我否则将永远不会被追踪。

为知识产权问题提供帮助,帮助我实现连接和绑定之间的区别。

3 个答案:

答案 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地址应该正确填充。

答案 1 :(得分:0)

在我的脑海中,您尝试将套接字绑定到地址为10.1.1.75的端点,但这似乎是一个远程端点?我想你想在本地绑定它并使用send_to,因为它是UDP

答案 2 :(得分: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有正确的价值!