我将udp单播数据包从windows发送到linux。
我已经使用boost编写了简单的应用程序udp客户端和srever。
我在Linux上运行客户端(udp sender)和Linux上的服务器(udp接收器)。
我的客户端正在发送udp数据包,但我在linux上的udp接收器没有收到数据包。但我可以看到wireshark上的udp数据包(它在我的linux上运行)。
我测试了端口和ipaddress,都是正确的。
下面是在linux上运行的代码。
如果我在Windows上同时运行(客户端和服务器),它可以正常运行
using boost::asio::ip::udp;
class udp_server
{
public:
udp_server(boost::asio::io_service& io_service)
: socket_(io_service, udp::endpoint(udp::v4(), 7799))
{
start_receive();
}
private:
void start_receive()
{
socket_.async_receive_from(
boost::asio::buffer(recv_buffer_), remote_endpoint_,
boost::bind(&udp_server::handle_receive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_receive(const boost::system::error_code& error,
std::size_t /*bytes_transferred*/)
{
if (!error || error == boost::asio::error::message_size)
{
start_receive();
}
}
udp::socket socket_;
udp::endpoint remote_endpoint_;
boost::array<char, 1> recv_buffer_;
};
int main()
{
try
{
boost::asio::io_service io_service;
udp_server server(io_service);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
答案 0 :(得分:2)
UDP是一种数据报协议。该协议是无状态的,数据包需要作为单个数据包接收。
有关背景信息,请参阅Beej's Guide to Networking。
然而,您的接收缓冲区是1个字节。你不能期望读取超过第一个字节。
这似乎可以从例如tutorial 6 listing。不同的是,这是一个日常服务,它不关心请求关注。所有它想知道的是“收到一个数据包”,它只会无条件地发送白天响应。
因此,解决方案似乎是增加缓冲区大小。如果无法预测/不限制包的大小,请考虑切换到流套接字(TCP / IP)。
这里,作为奖励,使用c ++ 11风格:
#include <boost/asio.hpp>
using boost::asio::ip::udp;
class udp_server
{
public:
udp_server(boost::asio::io_service& io_service)
: socket_(io_service, udp::endpoint(udp::v4(), 7799))
{
start_receive();
}
private:
void start_receive()
{
socket_.async_receive_from(
boost::asio::buffer(recv_buffer_), remote_endpoint_,
[this](boost::system::error_code ec, std::size_t bytes_transferred)
{
if (!ec && (bytes_transferred > 0))
{
std::cout << "PACKET[" << std::string(&recv_buffer_[0], &recv_buffer_[0]+bytes_transferred) << "]\n";
} else
throw ec; // TODO
start_receive();
});
}
udp::socket socket_;
char recv_buffer_[1024];
udp::endpoint remote_endpoint_;
};
int main()
{
std::cout << std::unitbuf;
try
{
boost::asio::io_service io_service;
udp_server server(io_service);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}