![](/img/trans.png)
[英]sendto returns with Invalid Argument on UDP Raw Socket ipv6 in Linux due to sin6_port value?
[英]invalid argument on boost asio udp socket connect (IPv6)
我一个小时都在苦苦挣扎:我想将boost asio udo套接字连接到端点。 在IPv4中这样做没有问题。 但是,如果我尝试在IPv6中执行相同的操作,则会收到错误代码“无效参数”。
using boost::asio::ip::udp;
struct UdpConnectionParams
{
udp::endpoint m_localEndpoint;
udp::endpoint m_remoteEndpoint;
}
boost::system::error_code setupUdpConnection(udp::socket& p_socket, const UdpConnectionParams& p_params)
{
// close socket
boost::system::error_code h_ignoreError;
p_socket.close(h_ignoreError);
// variables for kind of UDP connection
udp h_protocol(udp::v4());
bool h_shallBind{false};
bool h_shallConnect{false};
// determine kind of connection
if(p_params.m_localEndpoint != udp::endpoint())
{
h_protocol = p_params.m_localEndpoint.protocol();
h_shallBind = true;
}
if(p_params.m_remoteEndpoint != udp::endpoint())
{
h_protocol = p_params.m_remoteEndpoint.protocol();
h_shallConnect = true;
}
if(!h_shallBind && !h_shallConnect)
{
// no endpoint specified, return error
return boost::system::error_code(ENetworkErrorCode::NO_ENDPOINT_SPECIFIED, NetworkErrorCategory::getCategory());
}
try
{
p_socket.open(h_protocol);
//bind socket to certain endpoint
if(h_shallBind)
{
p_socket.bind(p_params.m_localEndpoint);
}
//connect socket to client. Thus it is possible to use p_socket.send()
if(h_shallConnect)
{
p_socket.connect(p_params.m_remoteEndpoint);
}
}
catch (boost::system::system_error& h_error)
{
p_socket.close(h_ignoreError);
return h_error.code();
}
// no error
return boost::system::error_code();
}
int main()
{
boost::asio::io_service service;
udp::socket socket(service);
boost::system::error_code error;
UdpConnectionParams params;
params.m_localEndpoint = udp::endpoint(udp::v6(), 55555);
params.m_remoteEndpoint = udp::endpoint(boost::asio::ip::address_v6::from_string("ff01::101"), 55555);
error = setupUdpConnection(socket, params);
cout << error << error.message() << endl; // "invalid argument"
return 0;
}
我没有错误的唯一方法是使用本地主机IP地址(:: 1)。 如果将套接字绑定到端点也没有区别。 我究竟做错了什么?
我究竟做错了什么?
问题是您没有在使用的IPv6地址中指定接口索引/范围。 IPv6多播地址需要指定范围,以便网络堆栈可以知道与IP地址关联的计算机的本地网络接口。
即代替:
boost::asio::ip::address_v6::from_string("ff01::101"), 55555);
您需要类似:
boost::asio::ip::address_v6::from_string("ff01::101%eth0"), 55555);
(当然,%符号后的后缀取决于您要使用的网络接口的名称)
(作为附带说明,“ ff01 ::”前缀用于节点本地IPv6多播组,这意味着您的UDP数据包将仅发送到同一台计算机上运行的其他程序。如果您打算这样做,那就太好了;在另一方面,如果您希望UDP数据包到达同一LAN上的其他计算机,则需要改用“ ff02 ::”或“ ff12 ::”前缀(ff02 ::代表知名多播地址ff12 ::代表临时多播地址。有关详细信息,请参见Wikipedia页面上的 “多播地址范围”表)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.