我对网络编程很陌生。
我写了下面的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正在接收的数据包中。
答案 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)
解决了眼前的问题。