gpt4 book ai didi

c++ - LAN 上的计算机使用 boost::asio C++ 无法持续​​接收到 255.255.255.255 的 UDP 广播

转载 作者:搜寻专家 更新时间:2023-10-31 00:53:18 24 4
gpt4 key购买 nike

我对网络编程还很陌生,但我正在从事一个需要在 LAN 上的两台计算机之间进行连接的个人项目。

对于我所有的网络需求,我都在使用 boost。

由于在 LAN 上运行我的软件的计算机不知道彼此的 IP 地址,程序立即向 255.255.255.255 发送 UDP 广播。另一台计算机在端口 25566 上监听。如果一台计算机收到广播,它会回复另一个广播,以确保另一台计算机以适当的方式通过 TCP 连接进行连接。

我有一台笔记本电脑和一台台式机,都运行 Linux。如果我在同一台机器上测试代码(同一事物的两个实例),一切都会完美无缺。但是,当我在笔记本电脑上运行一个实例,在台式机上运行另一个实例时,就会出现问题。发生两种情况:

第一个 - 我在台式计算机上运行该程序的一个实例。它发送一条“Hello”消息来检查是否有另一个实例正在 LAN 上的其他任何地方运行。由于没有其他实例在运行,因此它不会收到任何响应。几秒钟后,在桌面实例自行设置后,我在笔记本电脑上启动了该程序的一个实例。膝上型电脑也会广播一条“你好”消息。然而,这就是问题所在。当笔记本电脑发送“Hello”消息时,桌面程序(已经运行)实际收到消息的可能性只有 10%。我在台式机上使用 Wireshark 监控网络,同样,Wireshark 仅在 10% 的时间内从笔记本电脑接收广播。但是,如果我在发送“Hello”广播的笔记本电脑上运行 Wireshark,Wireshark 每次都会接收它。

第二个 - 这与第一个类似,除了笔记本电脑首先运行程序。然后我在几秒钟后启动桌面实例。然而,当台式机广播“Hello”时,笔记本电脑在大约 95% 的时间内接收到广播(相反,当角色互换时只有 10% 的时间)。然后膝上型计算机以“Configure”广播响应。然后桌面几乎 100% 的时间接收到“Configure”广播。我再次用 Wireshark 确认了 95% 的接收率。

我确信我的程序忽略这些数据包没有问题。但是,网络中发生了一些事情,广播数据包被忽略或过滤掉了。我发现特别奇怪的是,桌面程序如何在场景 1 中仅在 10% 的时间内收到“Hello”消息,但在场景 2 中却在 100% 的时间内收到“Configure”消息。如果发生奇怪的事情阻止了数据包从到达桌面,这两个百分比不会大致相等吗?

这是我运行的一些代码来设置必要的套接字:

broadcast_socket = new udp::socket(*ioservice); //Set up the socket that broadcasts the message
listen_socket = new udp::socket(*ioservice); //Set up the socket on port 25565 that listens for a broadcast

//Set up the ioservice...

error_code e1, e2;
broadcast_socket->open(udp::v4(), e1); //Actually open the sockets
listen_socket->open(udp::v4(), e2);

//Do some error code checking...

listen_endpoint = udp::endpoint(ip::address_v4::any(), port); //Get endpoint for port 25566 (listen_endpoint becomes 0.0.0.0:25566 after this call)

listen_socket->set_option(udp::socket::reuse_address(true));
listen_socket->bind(listen_endpoint);

broadcast_socket->set_option(udp::socket::reuse_address(true));
broadcast_socket->set_option(socket_base::broadcast(true));

broadcast_endpoint = udp::endpoint(ip::address_v4::broadcast(), port); //Get the broadcast_endpoint (returns 255.255.255.255)

这是我用来接收广播消息的代码:

error_code ec;
size_t available_bytes = listen_socket->available(ec); //See if data is available
size_t read_bytes = 0;
char buffer[1024];

if(available_bytes > 0 && !ec){
read_bytes = listen_socket->receive_from(boost::asio::buffer(buffer, (available_bytes < sizeof(buffer) ? available_bytes : sizeof(buffer))), listen_endpoint);

read_data.append(buffer, read_bytes); //Append to a string for later processing
}

最后,这是我发送数据的方式:

std::string payload = "Some payload stuff goes here";

broadcast_socket->send_to(boost::asio::buffer(payload, payload.size()), broadcast_endpoint); //Broadcasts to the broadcast_endpoint (255.255.255.255) which was determined earlier

所以基本上我的问题是,为什么我的一些广播没有通过?

谢谢

编辑:

此外,我忘了提及每台计算机每次都会收到自己的广播。所以我认为这是网络的问题,而不是我的代码。

最佳答案

UDP 不保证传送。这是协议(protocol)属性的一部分。

您可以使用 Wireshark 观察到该行为这一事实证实它与 Boost 几乎没有关系。

使用 255.255.255.255 是一把钝器,而且有限制:

Setting all the bits of an IP address to one, or 255.255.255.255, forms the limited broadcast address. Sending a UDP datagram to this address delivers the message to any host on the local network segment. Because routers never forward messages sent to this address, only hosts on the network segment receive the broadcast message.

使用子网掩码可以更有针对性:

Broadcasts can be directed to specific portions of a network by setting all bits of the host identifier. For example, to send a broadcast to all hosts on the network identified by IP addresses starting with 192.168.1, use the address 192.168.1.255.

这增加了路由器知道将数据包发送到哪里的机会(我不是网络工程师,所以我不确定实现细节)。

输入多播组:

Unlike broadcast transmission (which is used on some local area networks), multicast clients receive a stream of packets only if they have previously elect to do so (by joining the specific multicast group address). Membership of a group is dynamic and controlled by the receivers (in turn informed by the local client applications).

(来源:http://www.erg.abdn.ac.uk/users/gorry/course/intro-pages/uni-b-mcast.html)

这更可能适合您的应用。您必须根据网络配置选择一个好的组端点,因此它稍微复杂一些。

然而,您将获得所有现代路由器硬件/软件的支持,以确保交付给感兴趣的各方(仅)。

关于c++ - LAN 上的计算机使用 boost::asio C++ 无法持续​​接收到 255.255.255.255 的 UDP 广播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49224182/

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