Python Forum
UDP listener - why doesn't it work?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
UDP listener - why doesn't it work?
#1
I am a beginner in Python programming.
I wrote a short program that decodes the data received on the UDP port and starts playing the mp3 file on the Raspberry Pi Speaker output. "netstat -lnu" shows that the UDP port is open, ready to receive. The data does not arrive, so I checked the data arriving on the UDP port with Wireshark. The data is fine, and when Wireshark is running, the program works. If I stop Wireshark, the program does not work. How is it possible? What might be the problem?

import socket
import pygame

pygame.mixer.init()
UDP_IP = ""
UDP_PORT = 6767

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))

while True :
    rec, addr = sock.recvfrom(7)
    data = [x for x in rec]
    if data[0] == 170 and data[1] == 85 and data[2] == 133 and sum(data[2:6]) % 256 == data[6] :
        if data[4] == 109 and data[5] == 105 :
            pygame.mixer.music.load('/home/pi/Audio/1m.mp3')
            pygame.mixer.music.play()
Reply
#2
I see that no one has any idea how to solve the problem.
As an experiment, I created a UDP socket in PHP to check whether data is received there. It works the same way as a Python program. If Wireshark is running, there is data, if it is not running, there is no data on the output. Could this issue be related to the Raspberry Pi?
Reply
#3
To get it right, you have to send a bytes string with these values:
data =  bytes([170, 85, 133, 97, 109, 105, 188])


# doing the test manually

if bytes([170, 85, 133]) == data[0:3]  and bytes([109, 105]) == data[4:6]:
    print("First 3 bytes are right and byte 4 and 5 are right (from 0 on)")

if sum(data[2:6]) % 256 == data[6]:
    print("Calculation is ok")
Testing locally with Python:
from socket import AF_INET, SOCK_DGRAM, socket


with socket(AF_INET, SOCK_DGRAM) as sock:
    sock.sendto(bytes([170, 85, 133, 97, 109, 105, 188]), ("127.0.0.1", 6767))
The modified Server Code:

import socket

import pygame

pygame.mixer.init()
UDP_IP = ""
UDP_PORT = 6767

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))


def header_ok(data):
    return data[0:3] == bytes([170, 85, 133])


def tail_ok(data):
    return data[4:6] == bytes([109, 105])


def sum_ok(data):
    return sum(data[2:6]) % 256 == data[6]


while True:
    rec, addr = sock.recvfrom(7)
    if header_ok(rec) and tail_ok(rec) and sum_ok(rec):
        pygame.mixer.music.load("the_only_thing_they_fear_is_you.mp3")
        # https://www.youtube.com/watch?v=Aqk7x_w1H98
        pygame.mixer.music.play()
Even with your original code, it worked. The only thing I had to replace was the mp3 file.

I can't explain why it works only, if wireshark is running. Maybe there is a firewall in the way. The use of wireshark switches the network interface into promiscuous mode.

You could add some print functions (yes, print debugging is bad) to your code to see what happens.
Or look what you receive:
from socket import socket, AF_INET, SOCK_DGRAM


with socket(AF_INET, SOCK_DGRAM) as sock:
    sock.bind(("", 6767))
    try:
        while chunk := sock.recv(1024):
            print("Received raw:    ", chunk)
            print("Received as ints:", tuple(chunk))
    except KeybaordInterrupt:
        pass
This will print the raw bytes and as a tuple with integers.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#4
Thanks for the reply.
I understand the code you sent, but unfortunately it doesn't solve the problem. This also only works if Wireshark is running. I tried turning promiscuous mode off, but nothing changes.
The last block of code ("Or look what you receive:") also only gives results if Wireshark is running.
This python program (as well as Wireshark) runs on a Raspberry Pi, and the UDP data comes from a PLC.
Reply
#5
Look what iptables-save shows for rules. Maybe you or an application has made a rule to block UDP 6767, which should be in Promiscuous mode inactive. This could be the explanation why it works, if you run Wireshark.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#6
iptables-save -> command not found
The Pi runs Debian GNU/Linux 11 (bullseye), which is probably not part of this op. system.
Reply
#7
(Aug-04-2022, 01:14 PM)Surmi Wrote: The Pi runs Debian GNU/Linux 11 (bullseye)

It may very well be running ufw. Try sudo ufw status
Sig:
>>> import this

The UNIX philosophy: "Do one thing, and do it well."

"The danger of computers becoming like humans is not as great as the danger of humans becoming like computers." :~ Konrad Zuse

"Everything should be made as simple as possible, but not simpler." :~ Albert Einstein
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020