skip to Main Content

This is a python-related programming question that maybe cannot be answered at all. Maybe there is no solution.

But here is the setup: I am using Windows-10 on a hp laptop and a device in a local network sends out UDP packages for destination 239.0.0.4 and port 45004 (As can be confirmed via wireshark). That device is connected to a USB Ethernet connector named Ethernet with a static IP address 192.168.200.5 and subnetmask 255.255.255.0.

enter image description here

I am trying the following python (3.10.11) code to create a socket in order to read the packages from that device (the exact same python code works without any issues on Ubuntu on the same laptop and the same device):

import socket

mcast_grp = "239.0.0.3"
port = 45004
adaptor = "192.168.200.5"
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((mcast_grp, port))  # FAILING LINE
mreq = struct.pack("4s4s", socket.inet_aton(mcast_grp), socket.inet_aton(adaptor))
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

But that python code fails on the indicated line with the error

    sock.bind((mcast_grp, port))
OSError: [WinError 10049] The requested address is not valid in its context

Is there ANY way to rewrite this python code so it also works on windows?

2

Answers


  1. Chosen as BEST ANSWER

    To capture the data from an ethernet device using python on Windows-10 it is possible to use the third-party module pyshark. That allows to capture and select the requested packets from the device.

    Here is an example code how to do that:

    import pyshark
        
    def capture_ethernet_traffic(interface, destination_ip):
        capture = pyshark.LiveCapture(interface=interface)
        for packet in capture.sniff_continuously():
            # Select UDP packets directed to a certain IP address
            if "IP" in packet "UDP" in packet and packet.ip.dst == destination_ip:                   
                # Extract the data as bytes
                captured_data = bytearray.fromhex(packet.data.data)
                print(captured_data)
    
                # process that data as required
                ...
    
    interface = "Ethernet 7"  # Replace with your interface name
    destination_ip = "239.0.0.3"
    capture_ethernet_traffic(interface, destination_ip)
    

    Works like a charm...


  2. You can’t bind the socket to a multicast group IP, only to a local interface IP. So bind to the IP of a local adapter that you want to receive packets on, and then subscribe to the multicast group to indicate that you want to receive packets from it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search