https://github.com/thinkalvb/rtds-server我正在制作一个简单的UDP IPv6服务器,它打印远程endpoint发送的UDP数据包的版本。 但是这个代码的行为很奇怪。 当发送IPv6和IPv4数据包时,它将打印IPv6
。 我做错了什么? [在Win10中使用Packet Sender Portable 6.2.3(127.0.0.1和::1)进行测试]
#include <asio.hpp>
#include <iostream>
#include "udp_peer.h"
#include <thread>
asio::io_context ioContext;
asio::io_context::work worker(ioContext);
void runServer()
{
ioContext.run();
}
int main()
{
asio::ip::udp::endpoint mUDPep(asio::ip::udp::v6(), 321);
asio::ip::udp::socket mUDPsock(ioContext);
std::thread thread(runServer);
thread.detach();
asio::error_code ec;
UDPpeer udpPeer(&mUDPsock); // Ignore this, it contains the character array
asio::ip::udp::endpoint ep;
mUDPsock.open(mUDPep.protocol(), ec);
mUDPsock.bind(mUDPep, ec);
while (true)
{
auto dataSize = mUDPsock.receive_from(udpPeer.getReadBuffer(), ep);
if (ep.address().is_v4())
std::cout << "IPv4";
else
std::cout << "IPv6";
}
}
你只听V6。
eP
并不规定您如何接收。
您的v6端点能够同时接收这两种信息。 打印实际终结点以查看:
#include <boost/asio.hpp>
#include <iostream>
namespace asio = boost::asio;
using asio::ip::udp;
int main() {
asio::thread_pool context(1);
udp::socket sock(context, {udp::v6(), 8888});
udp::endpoint ep;
char arr[4096];
while (true) {
/*auto n =*/ sock.receive_from(asio::buffer(arr), ep);
std::cout
<< std::boolalpha << ep.address().is_v4() << " "
<< ep << "\n";
}
context.join();
}
现在发送两个数据包:
echo -n "hello world $RANDOM" | nc -6 -w 0 -u ::1 8888
echo -n "hello world $RANDOM" | nc -4 -w 0 -u 127.0.0.1 8888
打印:
false [::1]:49972
false [::ffff:127.0.0.1]:34368
作为比较,使用udp::socket sock(context,{udp::v4(),8888});
并不接收v6数据包:
true 127.0.0.1:39805
换句话说,因为您的套接字绑定到v6,所以您得到的地址被映射成好像用:
if (a.is_v4())
return asio::ip::address_v6::v4_mapped(a.to_v4());
检查v6是否与v4映射或兼容:
asio::ip::address_v4 a4;
if (a6.is_v4_compatible() || a6.is_v4_mapped())
a4 = a6.to_v4();
看起来更现代的界面应该是这样的
a4 = make_address_v4(asio::ip::v4_mapped, a6);
#include <boost/asio.hpp>
#include <iostream>
namespace asio = boost::asio;
using asio::ip::udp;
int main() {
asio::thread_pool context(1);
udp::socket sock(context, {udp::v6(), 8888});
udp::endpoint ep;
char arr[4096];
for (auto n=2; n--;) {
/*auto n =*/ sock.receive_from(asio::buffer(arr), ep);
asio::ip::address_v4 a4;
{
auto a6 = ep.address().to_v6();
if (a6.is_v4_compatible() || a6.is_v4_mapped())
a4 = a6.to_v4();
}
std::cout
<< (a4.is_unspecified()? "not-mapped" : a4.to_string()) << " "
<< ep << "\n";
}
context.join();
}
打印
127.0.0.1 [::ffff:127.0.0.1]:54859
not-mapped [::1]:36231