Zainab Abd
Posts: 6
Joined: Sun Dec 01, 2019 3:39 pm

UDP broadcast programming

Wed Dec 04, 2019 11:39 am

hello,
A few days ago I was asked you about broadcasting a message among set of raspberry pis

I am create the system that sends a broadcast of a message alert to all the nodes that are on the network.

Now I want each station that receives the message must transmit it to other stations on the networks it is connected except the sender to spread the message.

i created the client.py and the server.py , but I don't know how to make the station re-transmit the message to all except the sender one .
its the first time i am creating a project in networking programming in python.

#client.py
import socket

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
client.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

client.bind(("", 50000))

while True:

data, addr = client.recvfrom(1024)
print(('received message:') , data.decode("utf-8"))


#server.py
import socket
import time

server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
server.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
server.settimeout(0.2)

MSG = 'Hello, World!'
MESSAGE = str.encode(MSG)

while True:
server.sendto(MESSAGE, ('<broadcast>', 50000))
print("message sent!")
time.sleep(1)
Last edited by Zainab Abd on Wed Dec 04, 2019 6:49 pm, edited 2 times in total.

hippy
Posts: 6281
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: UDP broadcast programming

Wed Dec 04, 2019 2:22 pm

What is your '<broadcast>' in the above ?

This seems to be the earlier thread which appears to have stated what must be done -

https://www.raspberrypi.org/forums/view ... 6&t=258207

This works for me, Python 2, broadcast send -

Code: Select all

#!/usr/bin/python2

import socket

UDP_IP   = "192.168.0.255"
UDP_PORT = 5005

MESSAGE  = "Hello, World!"

print "UDP target IP   :", UDP_IP
print "UDP target port :", UDP_PORT
print "Message         :", MESSAGE

sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
sock.sendto( MESSAGE, (UDP_IP, UDP_PORT) )
sock.close()
Brodcast receive -

Code: Select all

#!/usr/bin/python2

import socket

UDP_IP   = "192.168.0.255"
UDP_PORT = 5005

print "UDP Receive IP   :", UDP_IP
print "UDP Receive port :", UDP_PORT

sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.bind( (UDP_IP, UDP_PORT) )

while True:
  data, addr = sock.recvfrom(1024)
  print "Received Data    :", data

Zainab Abd
Posts: 6
Joined: Sun Dec 01, 2019 3:39 pm

Re: UDP broadcast programming

Wed Dec 04, 2019 5:56 pm

hippy wrote:
Wed Dec 04, 2019 2:22 pm
What is your '<broadcast>' in the above ?

This seems to be the earlier thread which appears to have stated what must be done -

https://www.raspberrypi.org/forums/view ... 6&t=258207

This works for me, Python 2, broadcast send -

Code: Select all

#!/usr/bin/python2

import socket

UDP_IP   = "192.168.0.255"
UDP_PORT = 5005

MESSAGE  = "Hello, World!"

print "UDP target IP   :", UDP_IP
print "UDP target port :", UDP_PORT
print "Message         :", MESSAGE

sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
sock.sendto( MESSAGE, (UDP_IP, UDP_PORT) )
sock.close()
Brodcast receive -

Code: Select all

#!/usr/bin/python2

import socket

UDP_IP   = "192.168.0.255"
UDP_PORT = 5005

print "UDP Receive IP   :", UDP_IP
print "UDP Receive port :", UDP_PORT

sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.bind( (UDP_IP, UDP_PORT) )

while True:
  data, addr = sock.recvfrom(1024)
  print "Received Data    :", data
yes, It is,,, but now I am asking about how to make each station receive the message resend it to all surrounding nodes except the sender one

hippy
Posts: 6281
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: UDP broadcast programming

Wed Dec 04, 2019 6:28 pm

Zainab Abd wrote:
Wed Dec 04, 2019 5:56 pm
now I am asking about how to make each station receive the message resend it to all surrounding nodes except the sender one
I don't think you can. You can either rebroadcast the message, in which case everyone will receive it, which may well cause a network flood of messages, or send it specifically to every IP address on the subnet except the one it came from.

You could introduce some mechanism, so anyone receiving the message doesn't respond if it's already seen the message, which could curtail a flood.

It's not clear what issue you are trying to solve. Perhaps some detail on what you are trying to achieve as an end result will help identify the best solution.

User avatar
thagrol
Posts: 2001
Joined: Fri Jan 13, 2012 4:41 pm
Location: Darkest Somerset, UK
Contact: Website

Re: UDP broadcast programming

Wed Dec 04, 2019 7:01 pm

Zainab Abd wrote:
Wed Dec 04, 2019 5:56 pm
yes, It is,,, but now I am asking about how to make each station receive the message resend it to all surrounding nodes except the sender one
That sounds like a really bad idea. Once started you'll flood your entire network with messages.

Given a three machine network, A, B, and C.
  1. A sends initial message.
  2. B receives it and rebroadcasts it to C. At the same time C receives it and rebroadcasts to B.
  3. B and C then rebroadcast to A
  4. A receives broadcast from B and C. Rebroadcasts message from C to B and from B to C
  5. B receives message and rebroadcasts it to C. At the same time C receives it and rebroadcasts to B.
  6. B and C then rebroadcast to A
  7. Repeat steps 4 through 6 until the end of time.
Now image what happens with four or ten or a hundred machines.
Attempts to contact me outside of thes forums will be ignored unless signed in triplicate, sent in, sent back, queried, lost, found, subjected to public enquiry, lost again, and finally buried in soft peat for three months and recycled as firelighters

deepo
Posts: 262
Joined: Sun Dec 30, 2018 8:36 pm

Re: UDP broadcast programming

Wed Dec 04, 2019 7:02 pm

Could that not be built into the protocol, so that each message being broadcast has e.g. an ID, so you can broadcast all you want. All receivers only react once to that specific ID.

/Mogens

Zainab Abd
Posts: 6
Joined: Sun Dec 01, 2019 3:39 pm

Re: UDP broadcast programming

Wed Dec 04, 2019 7:12 pm

hippy wrote:
Wed Dec 04, 2019 6:28 pm
Zainab Abd wrote:
Wed Dec 04, 2019 5:56 pm
now I am asking about how to make each station receive the message resend it to all surrounding nodes except the sender one
I don't think you can. You can either rebroadcast the message, in which case everyone will receive it, which may well cause a network flood of messages, or send it specifically to every IP address on the subnet except the one it came from.

You could introduce some mechanism, so anyone receiving the message doesn't respond if it's already seen the message, which could curtail a flood.

It's not clear what issue you are trying to solve. Perhaps some detail on what you are trying to achieve as an end result will help identify the best solution.
Thanks a lot ,, I thought about the first suggestion and did not implement it for the same reason you mentioned . My end result is to spread an alert message so when there is an abnormal situation one raspberry pi can sense it and send a message to the surrounding Pis , each PI receive that message it also spread it to the surrounding Pis except the sender one . The second suggestion seems right to me

User avatar
DougieLawson
Posts: 36578
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website Twitter

Re: UDP broadcast programming

Wed Dec 04, 2019 7:13 pm

It has to be said that one-to-one, one-to-many, many-to-one and many-to-many messaging is best done with MQTT.

The system with the message publishes it on their MQTT topic. The systems that are interested subscribe to that topic (or a wild-card topic that covers it).

No guessing who the sender is, no guessing who's interested in receiving the message (that stuff is all done by HiveMQ, RabbitMQ or Mosquitto). No low level socket programming. It's a layer 4 API for MQTT. There's even websockets support in Mosquitto (haven't checked if that's in HiveMQ or RabbitMQ).

https://www.hivemq.com/mqtt-essentials/
Note: Having anything humorous in your signature is completely banned on this forum. Wear a tin-foil hat and you'll get a ban.

Any DMs sent on Twitter will be answered next month.

This is a doctor free zone.

Zainab Abd
Posts: 6
Joined: Sun Dec 01, 2019 3:39 pm

Re: UDP broadcast programming

Wed Dec 04, 2019 7:17 pm

thagrol wrote:
Wed Dec 04, 2019 7:01 pm
Zainab Abd wrote:
Wed Dec 04, 2019 5:56 pm
yes, It is,,, but now I am asking about how to make each station receive the message resend it to all surrounding nodes except the sender one
That sounds like a really bad idea. Once started you'll flood your entire network with messages.

Given a three machine network, A, B, and C.
  1. A sends initial message.
  2. B receives it and rebroadcasts it to C. At the same time C receives it and rebroadcasts to B.
  3. B and C then rebroadcast to A
  4. A receives broadcast from B and C. Rebroadcasts message from C to B and from B to C
  5. B receives message and rebroadcasts it to C. At the same time C receives it and rebroadcasts to B.
  6. B and C then rebroadcast to A
  7. Repeat steps 4 through 6 until the end of time.
Now image what happens with four or ten or a hundred machines.


Yes , you are right , I am trying to prevent the flood by exclude the node that send the message from receiving it again .. This is my issue

User avatar
DougieLawson
Posts: 36578
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website Twitter

Re: UDP broadcast programming

Wed Dec 04, 2019 7:20 pm

Zainab Abd wrote:
Wed Dec 04, 2019 7:17 pm

Yes , you are right , I am trying to prevent the flood by exclude the node that send the message from receiving it again .. This is my issue
MQTT includes a quality of service flag for "at most once (QOS0)", "at least once (QOS1)" and "exactly once (QOS2)" delivery of your messages.
Note: Having anything humorous in your signature is completely banned on this forum. Wear a tin-foil hat and you'll get a ban.

Any DMs sent on Twitter will be answered next month.

This is a doctor free zone.

User avatar
thagrol
Posts: 2001
Joined: Fri Jan 13, 2012 4:41 pm
Location: Darkest Somerset, UK
Contact: Website

Re: UDP broadcast programming

Wed Dec 04, 2019 7:59 pm

Zainab Abd wrote:
Wed Dec 04, 2019 7:17 pm
Yes , you are right , I am trying to prevent the flood by exclude the node that send the message from receiving it again .. This is my issue
Sounds like DougieLawson's suggestion of using MQTT would handle this problem but MQTT requires a broker and if the borker is down...

A couple of other suggestions:
  • Send the message a few times and assume the other nodes have received it.

    Easiest to code but not especially reliable
  • Send the message as a broadcast but require that all nodes acknowledge receipt to the sender. If a node deosn't acknowledge in a reasonable time frame resend only to that node. You'd probaly want a cap on the number of resends to a node.

    More complex to code, needs a way of identifying which message is being ack'd.
  • Embed a unique ID into each message when it is first sent. If a node has already rebroadcast a message with that ID don't broadcast it again. Still some flooding but much less than with yout original scheme and it will stop once every node has sent the message once.

    The problem here though is keeping message IDs unique both between messages and across originators.

The correct/best solution depends on what the actual problem you're trying to solve is. Sending a UDP broadcast (whether relayed or not) may not be it.

I suspect others have had the same or a very similar requirement, an internet search may help.
Attempts to contact me outside of thes forums will be ignored unless signed in triplicate, sent in, sent back, queried, lost, found, subjected to public enquiry, lost again, and finally buried in soft peat for three months and recycled as firelighters

hippy
Posts: 6281
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: UDP broadcast programming

Wed Dec 04, 2019 8:30 pm

One question must be; what are the circumstances such that one Pi might not receive the alert from an originator, but will then see it from a rebroadcaster ?

Any blind transmitting solution would have to repeat continually to ensure all have got the alert, and any curtailing of a potential flood could see rebroadcasting end before the Pi not seeing it is able to so then never gets it.

It may be that the problem to be solved has no solution or needs to be implemented in a different way, perhaps multiple ways.

Another way to consider things may be with 'keep alive' messages so a Pi which has gone off-network can know that's happened. But whether useful or not depends on what one ultimately wants to achieve.

Zainab Abd
Posts: 6
Joined: Sun Dec 01, 2019 3:39 pm

Re: UDP broadcast programming

Thu Dec 05, 2019 12:20 pm

thagrol wrote:
Wed Dec 04, 2019 7:59 pm
Zainab Abd wrote:
Wed Dec 04, 2019 7:17 pm
Yes , you are right , I am trying to prevent the flood by exclude the node that send the message from receiving it again .. This is my issue
Sounds like DougieLawson's suggestion of using MQTT would handle this problem but MQTT requires a broker and if the borker is down...

A couple of other suggestions:
  • Send the message a few times and assume the other nodes have received it.

    Easiest to code but not especially reliable
  • Send the message as a broadcast but require that all nodes acknowledge receipt to the sender. If a node deosn't acknowledge in a reasonable time frame resend only to that node. You'd probaly want a cap on the number of resends to a node.

    More complex to code, needs a way of identifying which message is being ack'd.
  • Embed a unique ID into each message when it is first sent. If a node has already rebroadcast a message with that ID don't broadcast it again. Still some flooding but much less than with yout original scheme and it will stop once every node has sent the message once.

    The problem here though is keeping message IDs unique both between messages and across originators.
Thank you so much ,, good suggestions I am going to think about them


The correct/best solution depends on what the actual problem you're trying to solve is. Sending a UDP broadcast (whether relayed or not) may not be it.

I suspect others have had the same or a very similar requirement, an internet search may help.

Return to “Networking and servers”