数据报正在发送,但尚未收到+其他问题

时间:2015-09-27 07:37:23

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

我对网络编程很陌生。

我写了下面的exe,然后我在我的本地网络上的两台独立的机器上执行了。这个想法是它产生一个线程来监听和响应特定端口上的数据报,然后在主线程中它允许用户发送数据。

通过Wireshark,我可以看到从其他机器发送的数据报,在正确的端口上击中这台机器,但是我的exe没有对它作出反应。我无法看到我的异步接收的哪一部分不正确。

同样在Wireshark中我可以看到发送消息被发送到正确端口上的正确机器IP,再次,在另一台机器上.exe似乎没有收到消息。

我做错了什么?

class UDPConnector
{
public:
    UDPConnector(asio::io_service& io_service)
    : m_socket(io_service)
    {
        auto endpoint = asio::ip::udp::endpoint(asio::ip::udp::v4(),34724);
        m_socket.open(endpoint.protocol());
        m_socket.bind(endpoint);

        StartReceiving();
    }

protected:

    void StartReceiving()
    {
        m_socket.async_receive_from(asio::buffer(m_receiveBuffer), m_remoteEndpoint,
                                    std::bind(&UDPConnector::HandleReceive, this,
                                              std::placeholders::_1,
                                              std::placeholders::_2));
    }

    void HandleReceive(const asio::error_code& error, std::size_t bytes)
    {
        if(!error)
        {
            std::stringstream ss;
            for(auto c : m_receiveBuffer)
                ss << c;
            std::cout << "received: " << ss.str() << std::endl;

            /* listen for the next post */
            StartReceiving();
        }
        else if(error == asio::error::message_size)
        {
            std::cout << "Message was larger than receive buffer" << std::endl;
        }
    }

    asio::ip::udp::socket m_socket;
    asio::ip::udp::endpoint m_remoteEndpoint;
    std::vector<char> m_receiveBuffer;
};

asio::io_service io_serviceListen;

void Listen()
{
    UDPConnector udpServer(io_serviceListen);
    io_serviceListen.run();
}

int main()
{
    std::thread listenThread(Listen);

    asio::io_service io_serviceSend;
    asio::ip::udp::resolver resolver(io_serviceSend);

    std::string dest;
    std::cout << "dest: ";
    std::cin >> dest;
    std::cout << std::endl;

    while(1)
    {
        std::cout << "Broadcast something: " << std::endl;
        std::string msg;
        std::cin >> msg;

        if(msg == "exit")
            break;

        asio::ip::udp::resolver::query query(asio::ip::udp::v4(), dest, "34724");
        asio::ip::udp::endpoint receiverEndpoint = *resolver.resolve(query);
        asio::ip::udp::socket socket(io_serviceSend);
        socket.open(asio::ip::udp::v4());
        socket.send_to(asio::buffer(msg), receiverEndpoint);
    }

    io_serviceListen.stop();
    listenThread.join();

    return 0;
}

我还有另一个副手问题。我在wireshark中注意到,尽管发送到特定端口,源端口是一些随机数。为什么会这样,我认为它会通过同一个端口。

修改

所以我已经知道我正在接收.exe中的数据包,但是有些错误。在HandleReceive成员中,我发现有一个asio :: error_code 234More data is available)并且bytes参数为0.

我在asio参考资料中找不到任何指定接收不同错误的方式和时间的内容。在Wireshark中,我可以看到数据位于.exe正在接收的数据包中。

1 个答案:

答案 0 :(得分:1)

我在asio文档中找到了答案。事实证明asio::buffer并不像我想象的那样。它需要提供一个连续的内存数组(std::vector提供)但是它需要有一个实际使用的设置大小。

ASIO不会调整std::vector的大小以填充数据包的内容。它只使用向量的.size(),在本例中为0.错误是说还有更多数据可用,因为它没有将任何数据放入提供的缓冲区(因为它是0长度)。

所以将UDPConnector构造函数更改为:

UDPConnector(asio::io_service& io_service)
: m_socket(io_service), m_receiveBuffer(128)

解决了眼前的问题。