gpt4 book ai didi

c++ - Asio 同步 IPv6 UDP 服务器

转载 作者:行者123 更新时间:2023-12-01 14:47:25 25 4
gpt4 key购买 nike

https://github.com/ThinkalVB/RTDS-Server
我正在制作一个简单的 UDP IPv6 服务器,它打印远程端点发送的 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

For comparison, saying udp::socket sock(context, {udp::v4(), 8888}); instead simply doesn't receive the v6 packet:

true 127.0.0.1:39805

换句话说,因为您的套接字绑定(bind)到 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();

Looks like the more modern interface for this is going to be something like

 a4 = make_address_v4(asio::ip::v4_mapped, a6);

演示: Live On Coliru
#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

关于c++ - Asio 同步 IPv6 UDP 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62728636/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com