Comments (10)
ZeroMQ book says that using the 255.255.255.255 broadcast will not send it on all interfaces, if you have more than one.
from simpdiscover.
👋 192.168.2.255 would work, but it's technically a directed broadcast.
if you're attached to 192.168.2.0/24 it will get converted a L2 broadcast, otherwise it will be sent to the your default router... if your router is attached to the network, it will send it as a L2 broadcast, otherwise it will get routed to a router that is connect to that network and then eventually end up as a broadcast.
in theory at least...
because in practice it was directed broadcast is usually disabled on routers
255.255.255.255 will broadcast to the local network only. if you have multiple interfaces though I'm not sure which one would get picked, but my understanding is that it will indeed pick only one.
Update:
When sending, a socket bound with INADDR_ANY binds to the default IP address, which is that of the lowest-numbered interface.
So as you bind to 0.0.0.0:0
then the lowest numbered interface would be picked to send the broadcast.
from simpdiscover.
When I tried the alternate broadcast address, nothing worked, even within subnet....I can retry though.
from simpdiscover.
I'm currently porting some C++ code to Rust and while porting our network code I ran into the issue you describe here. I can broadcast with Rust sockets using 255.2555.255.255 but not with other valid broadcast addresses. This works fine in C++ using native Windows and Linux sockets, as well as Boost ASIO sockets but for the life of me haven't managed to get this working in Rust.
So far I've tried tokio UdpSocket the std UdpSocket and event manipulating socket options with socket2 crate.
I feel like I'm clearly missing something. I have multicast working and unicast just not broadcast.
Did you ever find a solution to this issue?
from simpdiscover.
Looking back at my code I see I added this comment that explains all I have found out to date
/// A broadcast address is always relative to a given network. When you have a network, you can
/// compute its broadcast address by replacing all the host bits with 1s; simply put, the broadcast
/// address is the highest numbered address you can have on the network, while the network address
/// is the lowest one (with all host bits set to 0s); this is why you can't use either of them
/// as actual host addresses: they are reserved for this use.
///
/// If your network is `192.168.1.0/24`, then your network address will be `192.168.1.0`
/// and your broadcast address will be `192.168.1.255`
///
/// If your network is `192.168.0.0/16`, then your network address will be `192.168.0.0`
/// and your broadcast address will be `192.168.255.255`
///
/// `255.255.255.255` is a special broadcast address, which means "this network".
/// It lets you send a broadcast packet to the network you're connected to, without actually
/// caring about its address.
///
/// See [wikipedia article](https://en.wikipedia.org/wiki/Broadcast_address) for more info
const BROADCAST_ADDRESS : &str = "255.255.255.255";
```
I copied that from some other post I found.
I have not found a way to get broadcasts to work from an address other than that, and I have it hardcoded in this lib.
:-(
from simpdiscover.
Hmmm, ok weird. A socket should allow sending to a valid broadcast address so long as it's configured correctly.
Frustratiung as this "Just works" in C++ by various means.
I suppose either something is inherently being disallowed in Rust's socket implementation and/or there is some option that needs to be enabled for it to fully work. Although I think I have all the required options set, Basically I have duplicated the socket options we set in our C++ code using the equivalent functions and settings within Rust's sockets.
I guess I'll keep digging.
Thanks for the reply.
from simpdiscover.
Maybe try an issue to the rust source repo responsible for the networking calls, with a reproduction (rust playground) and sample C++ calls that work?
from simpdiscover.
Solved the problem. It's the bind("0.0.0.0:0").
For the sending socket to broadcast (to all legal broadcasts addresses you could define) you need to create a socket without binding it then setup up the required options. You cannot do this with the std::net:UdpSocket or tokio::net::UdpSocket.
However, you can do this if you use the crate socket2. You can then setup your socket from scratch using socket2, then convert to std::net::UdpSocket, then to something like tokio::net::UdpSocket.
For example:
let actual_socket_buf_size: usize = 8388608;
let socket2 = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP))
.into_diagnostic()
.wrap_err("Failed to create new socket2::Socket with Domain::IPV4, Type::DGRAM, Protocol::UDP.")?;
socket2
.set_send_buffer_size(actual_socket_buf_size)
.into_diagnostic()
.wrap_err("Failed to set SO_SNDBUF.")?;
socket2
.set_nonblocking(true)
.into_diagnostic()
.wrap_err("Failed to set nonblocking mode.")?;
socket2
.set_broadcast(true)
.into_diagnostic()
.wrap_err("Failed to set SO_BROADCAST.")?;
let std_socket: std::net::UdpSocket = socket2.into();
self.socket= tokio::net::UdpSocket::from_std(std_socket)
.into_diagnostic()
.wrap_err("Failed to convert to tokio::net::UdpSocket.")?;
Then I can send using:
let bytes_sent = self.socket
.send_to(buffer, self.target)
.await
.into_diagnostic()
.wrap_err("Failed to send message via UDP socket.")?;
Setting up a receiving socket is as before and should obviously still be bound correctly.
Using this I can send to 160.51.255.255 and I receive the messages.
Hope ths is of use to you, thought I'd let you know how to solve it.
Edit: Reason I discovered this was reviewing my C++ code both our very old native socket code using WInsock plus our modern C++17 code using boost ASIO sockets, where I realised I never bind the UDP socket for sending only receiving.
from simpdiscover.
Nice work, well done!
Maybe document that (for rust) somewhere that other searchers will find!
Closing issue, if that is OK?
from simpdiscover.
Go for it. Yes will try and put this on Rust forums somewhere when I get a spare moment.
from simpdiscover.
Related Issues (7)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from simpdiscover.