正在发送数据报,但没有收到数据报+附加问题

Datagrams are being sent, but not being received + additional questions

本文关键字:数据报 问题      更新时间:2023-10-16

我对网络编程很陌生。

我写了下面的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 234 (More data is available), bytes参数为0。

我在asio参考资料中找不到任何指定如何以及何时接收不同错误的内容。在Wireshark中,我可以看到数据在.exe接收的数据包中。

我在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)

解决了当前的问题