I am currently setting up a python socket for receiving UDP packets via ethernet and have problems with configuring the socket for obtaining data.
The ethernet adapter is configured with a fixed IP address. Using tcpdump, I am able to view the incoming UDP packets (as seen here) on port 4098, IP 192.168.33.30.
I am using the following example code for the socket:
import socket
UDP_IP = "192.168.33.30"
UDP_PORT = 4098
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(4096)
print("received message: %s" % data)
Unfortunately, there is no data return, even if the UDP packets are constantly send to the device. I am using a NVIDIA Jetson NX with Ubuntu 18.04.
So far I have checked the firewall and disabled it completely, but things did not change.
I am thankful for every advice on further troubleshooting!
Related
I am using raspberry pi 4 model B, and I am trying to communicate with my pc using Ethernet. I wrote a python code that create a socket with the following:
import socket
UDP_IP = "127.0.0.1"
UDP_PORT = 5005
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024)
This code worked over the wifi, so I googled it and I found that we should use “socket.AF_PACKET” instead. Does someone have any idea?
Also I noticed that there is 2 ip when I write ifconfig, one is under lo and the other is under wlan0.
lo, 127.0.0.1 is loopback and is only applicable to the system it is seen on. Virtually all systems will have one. You should use the IP address from wlan0.
When I try to ping a Minecraft server via LAN, the documents say the following:
In Singeplayer there is a function called "Open to LAN". Minecraft (in the serverlist) binds a UDP port and listens for connections to 224.0.2.60:4445 (Yes, that is the actual IP, no matter in what network you are or what your local IP Address is)" ....... client side, bind a UDP socket and listen for connections. You can use a MulticastSocket for that.
I tried to implement this in Python in the following way:
import socket
UDP_IP = "224.0.2.60"
UDP_PORT = 4445
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print("received message: %s" % data)
Which gave me an OSError: [WinError 10049] error.
Please help :( I have no idea what's wrong with my code.
By the way, sending packets to that port works, and the fake server shows up on the Minecraft app.
You cannot bind to a multicast address like that. It is somewhat more involved.
I recommend to read this article that explains all the details of using multicast with Python.
I have a Windows machine where I have two scripts that send and receive messages via UDP multicast (on the same machine). I have a C and Python3 implementation of this. The Python3 one looks like this:
sender.py
import socket
MCAST_GRP = '239.1.1.1'
MCAST_PORT = 1234
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
print("Sending")
sock.sendto(bytearray("str()", "utf-8"), (MCAST_GRP, MCAST_PORT))
data, address = sock.recvfrom(1024)
print('received %s bytes from %s' % (len(data), address))
print(data)
receiver.py
import socket
import struct
import sys
multicast_group = '239.1.1.1'
server_address = ('', 1234)
# Create the socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Bind to the server address
sock.bind(server_address)
# Tell the operating system to add the socket to the multicast group
# on all interfaces.
group = socket.inet_aton(multicast_group)
mreq = struct.pack('4sL', group, socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
# Receive/respond loop
while True:
print('\nwaiting to receive message')
data, address = sock.recvfrom(1024)
print('received %s bytes from %s' % (len(data), address))
print(data)
print('sending acknowledgement to', address)
sock.sendto(bytearray("ack", "utf-8"), address)
I have another physical device hooked up to the same machine but I cannot receive any messages from it with my programs. I can see that Wireshark is seeing the messages from the other physical device, these messages are coming over the eth0 interface to the same IP and Port. I know that the traffic generated by my scripts is on the VirtualBox Host-Only Network. I am not sure if that could cause the issue of me not seeing the UDP multicast messages from the external device.
I have tested it on a Linux machine as well (latest kali version) but could not receive any messages from the external device as well.
If I am missing some information, please let me know.
EDIT 1:
My setup is as follows:
I am running a native Windows 10 machine. To this machine is a device connected that is running some OS I don't know. I am only able to send and receive messages from it. I can send Ethernet, TCP, and IPv4 packets over the physical ethernet port on my Windows 10 machine by specifying the software I am using for this to use eth0 and a defined IP(v4) address I assigned to that port in the network adapter settings (192.168.1.100)
The scripts are running on the same Windows 10 machine that is also connected to the device. They are sending on this interface VirtualBox Host-Only Network but I don't know why. I did not configure anything like this. I assume that the interface should not be a problem because that is how UDP Multicast works (I am not sure of that so if I am mistaken please let me know!)
A sample output of the sender looks like this:
Sending
received 3 bytes from ('192.168.56.1', 3000)
b'ack'
Process finished with exit code 0
and the receiver:
waiting to receive message
received 5 bytes from ('192.168.56.1', 55132)
b'robot'
sending acknowledgement to ('192.168.56.1', 55132)
waiting to receive message
I hope that clarifies the setup. If there is still information missing please let me know!
As covered in https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html, the sockets API requires that you identify the interface as well as the multicast address/port you want to use.
By not specifying this in your sample code, you have left this down to the OS to pick and it has picked a VirtualBox Host-Only Network. Unfortunately this type of network is limited to VMs running on the Windows machines.
To fix it, you need to identify the interface that you want to use for the multicast and pass that in to your sending and receving code. For example:
sender.py
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(MCAST_IF_IP))
receiver.py
mreq = struct.pack('4s4s', group, socket.inet_aton(MCAST_IF_IP))
where MCAST_IF_IP is the IP address of the interface that you want to use.
I have arduino project using uno and ethernet shield. I wan't to print arduino data output in python. I have done try this case using pySerial python and successful.
Then now, I wan't to try my python can read arduino data output over internet, not serial python.
Topology:
Arduino with eth. shield--->switch<---laptop
*Note: the switch have internet connection from my router.
Can you help me, guys?
The IP that you use here should be "localhost" since only the arduino needs the address of the computer and not the other way around. Your Python script is just listening for anyone to connect. Try this:
import socket
UDP_IP = "localhost" # this computer
UDP_PORT = 3939 # the port that the arduino should connect to
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "received message:", data
I'm building a simple client-server multiplayer game and I want to have connected UDP sockets. However, when I call the listen() method it produces Operation not supported exception.
try:
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind((host, port))
server.listen(5)
except socket.error, (value, message):
print "E: " + message # E: Operation not supported
Is there a way to have connected datagram sockets?
UDP protocol is connectionless and thus you really cannot create connections between 2 sockets in the same manner as with the TCP client and server; thus you also cannot do the listen system call on an UDP socket, as it concerns only the TCP server sockets. Instead you use socket.recvfrom to receive datagrams from any address:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((host, port))
data, addr = sock.recvfrom(65536) # this will fit the maximum datagram
You can respond to the client (if they still have a socket open), by destructuring the addr which is a host, port tuple for socket.AF_INET, socket.SOCK_DGRAM.
client_host, client_port = addr
You can send data back there with sendto
sock.sendto(data, (client_host, client_port))
If you want to use a well-known port, you will bind the socket; if not, the system will assign a port for you.
It is possible to do a connect system call with datagram sockets on many socket implementations; this serves as a sort of filter, that drops the packets coming from unwanted sources, and for setting the default outgoing address for sock.send (it is still OK to use sock.sendto on such socket to another address, though the response might be dropped because of the "connection"). This is very useable on a client or between 2 nodes if they agree to use 2 well known ports with each other.
However if you do connect on server, it cannot serve any other requests on this socket. Also, listen with its queues only relates to SOCK_STREAM sockets.
Thus in case of many clients to 1 server, you could have the server listen to socket 12345, and when a client contacts the server, the server could respond from server:12345 with a message that contains another port number that the client should use with the server.