I am attempting to send packets to my "wifi lights" lighting system (like Philips Hue). I have documentation here that describes needing to send udp packets to my "bridge" using port 8899 which I have the IP address for.
All UDP Commands are 3 Bytes.
i.e. to turn all RGBW COLOR Wifi Lights Smart lights to ON then send
the TCP/IP UDP packet of: 0x42 0x00 0x55
The only way I could figure how to do in python was to chain them together as MESSAGE below. sendto() requires a string and won't accept hex or int.
import socket
UDP_IP1 = '192.168.0.104'
UDP_PORT = 8899
MESSAGE = str(0x410055)#0x410055
print "UDP target IP:", UDP_IP
print "UDP target port:", UDP_PORT
print "message:", MESSAGE
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
However I consistently get this error.
File "C:\3_test\wifilight_py.py", line 37, in <module>
sock.sendto(str(e), (UDP_IP, UDP_PORT))
socket.error: [Errno 10013] An attempt was made to access a socket in a way forbidden by its access permissions
[Finished in 0.5s]
This despite windows firewall being disabled completely (windows 7 / Python 2.7).
I am at my wit's end, I am not sure how I should troubleshoot this. I have Wireshark installed but it provides a huge dump of information and nothing related.
Related
I'm trying to receive UDP Broadcast packets sent from FPGA connected via a LAN cable. the FPGA sends continuous packets to port 5001.
My python receiver code is simple:
from socket import *
s=socket(AF_INET, SOCK_DGRAM)
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
s.bind(('', 5001))
print "trying to receive"
msg = s.recvfrom(1024)[0]
print msg
print "I'm outta here! Bye!"
I checked using Wireshark, and I found that the PC receives the packets. However, my Python code doesn't. I also checked sending packets from another local python code (to the same address and port) and my receiver got those packets.
Wireshark captures:
The issue was the firewall permissions for python
Ok im going to try an explain what is going on here... I have a network of multiple same type devices. I have a program that runs on any pc on the network that discovers these individual devices and categorizes them by ip, name, mac, etc.. This program allows for configuration of each device. The devices broadcast a udp packet to "255.255.255.255" with the information for discovery. I can run wireshark and intercept the packets broadcasted from the devices. I have a python program that will broadcast udp packets with data of my choosing.. Now.. This stems from me learning python and my project oriented approach.. I learn better this way :). Ok that being said.. My idea is to broadcast the exact udp packet that another device broadcasts, which in turn should land me on the discovery software as a particular network device.. By following udp stream in wireshark i can copy the data and enter it in my python program and broadcast it on the network. I can broadcast to any destination ip and see it in wireshark but when i try and send it to 255.255.255.255 it never shows up. Now i understand that routers will not forward 255x4 broadcasts pass the local network. When i run the discovery program i can see all the devices broacasting their packets to 255x4 but not the packet originating from my pc. Any ideas would be greatly appreciated.
Python Code:
import udp
import socket #for sockets
import sys #for exit
# create dgram udp socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except socket.error:
print 'Failed to create socket'
sys.exit()
host = '255.255.255.255';
port = 55558;
while(1) :
msg = '''...z..
hrQT.b.......hrQT.b
.....w...NanoStation M2...N2N
..Test......"XM.ar7240.v5.6.2.27929.150716.1201........NanoStation M2'''
try :
#Set the whole string
s.sendto(msg, (host, port))
# receive data from client (data, addr)
d = s.recvfrom(1024)
reply = d[0]
addr = d[1]
print 'Server reply : ' + reply
except socket.error, msg:
print 'Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
To receive UDP packets, you need to bind the socket to the IP address and UDP port that you want to receive packets on.
1 import socket
2
3 UDP_IP = "127.0.0.1"
4 UDP_PORT = 5005
5
6 sock = socket.socket(socket.AF_INET, # Internet
7 socket.SOCK_DGRAM) # UDP
8 sock.bind((UDP_IP, UDP_PORT))
9
10 while True:
11 data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
12 print "received message:", data
I would recommend using different UDP sockets for sending and receiving packets.
I have realy simple python27 script on Windows10
It is just sends messages and waits for reply using udp socket
import socket
UDP_IP = "127.0.0.1"
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, # Internet
socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
sock.recvfrom(1200)
On Windows 10 it raises exception
Traceback (most recent call last):
File "simple.py", line 14, in <module>
print sock.recv(1200)
socket.error: [Errno 10054]
On Linux it works fine.
What i am doing wrong ?
The first several lines of your program are opening a socket to send data which all is fine. But the sock.recvfrom line doesn't have an associated bind with it.
In other words, when you send on UDP you shouldn't expect to receive anything back. If you want to send a message and then wait for a reply (which will not be automatic from a remote system) you need to bind the socket to a listening port.
This site: https://wiki.python.org/moin/UdpCommunication has some great references.
I found solution here Windows UDP sockets: recvfrom() fails with error 10054 Author made the same. He ignores this error. But maybe it is true way of solving this problem.
I just put recvfrom in while and wrapped it with try..except
And I ignore any errors. It worked for me
Facts & context elements:
I need to capture data (latitude,longitude) coming out of a GPS device rework them and make them suitable for another application (QGIS). To this end I've tried to perform (What I thought at first would be a simple one) a python based module.
According to wire shark analysis.
Source Destination Protocol length info
192.168.0.1 225.2.5.1 UPD 136 source port : 1045 destination port:6495
I've tried this code found on various sources, like this one.
import socket
import os
UDP_IP = "225.2.5.1"
UDP_PORT = 6495
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(4096) # buffer size is 1024 bytes
print "received message:", data
os.system("pause")
The problem
This code doesn't work for me.The console windows whether collapse (despite the os.system("pause") or run indefinitely. As I'm not very skilled in python programming nor networking I've tested the provided code with the other IP address and port. As no result came from it I've also started to mix both of them. And finally, gave up and decided to share my issue with the community.
The aim :
I need to be able to access the data contains in this UDP frame with python 2.7 save them in a variable (data) for the next step of my programming project.
Thanks for reading and for your help
You should start your python program from the windows cmd-console or powershell, not from the explorer, then the window stays open and you see error messages. Remove the indentation error and the last line. Be sure, that your computer has the given IP-address. Bind your socket to any address:
import socket
UDP_IP = "0.0.0.0"
UDP_PORT = 6495
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:", data
I am trying to create a raw socket in Python that listens for UDP packets only:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
s.bind(('0.0.0.0', 1337))
while True:
print s.recvfrom(65535)
This needs to be run as root, and creates a raw socket on port 1337, which listens for UDP packets and prints them whenever they are received; no problems there.
Now let's make a little client to test if this works:
import socket
c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
c.connect(('127.0.0.1', 1337))
c.send('message 1')
c.send('message 2')
c.send('message 3')
c.send('message 4')
c.send('message 5')
c.send('message 6')
Consistently, only the first, third, and fifth message (message 1, message 3 and message 5) will get through and be printed in the server output. The second, fourth, and sixth messages do not show up on the server output, and instead the client gets an exception:
>>> c.send('message 2')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
socket.error: [Errno 111] Connection refused
Running this in Wireshark shows that it is getting an ICMP reply for "Destination unreachable". I have been able to reproduce this on 3 distinct machines (all running Linux though). Am I missing something? Is this expected behaviour for UDP to consistently drop packets, since protocols using it are supposed to be tolerant of packet loss? Even so, why would packets be dropped when sent on the local interface?
Binding the server to 127.0.0.1 instead of 0.0.0.0 has the same result.
Solved it in kind of a silly manner; please let me know if there is another way, and I will change the accepted answer.
The solution is simply to use two sockets bound on the same port; one raw, one not raw:
import socket, select
s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s1.bind(('0.0.0.0', 1337))
s2 = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
s2.bind(('0.0.0.0', 1337))
while True:
r, w, x = select.select([s1, s2], [], [])
for i in r:
print i, i.recvfrom(131072)
This makes the "Destination unreachable" ICMP packets go away and makes all packets go through fine. I think the operating system wants a non-raw socket listening on the port for things to go well, and then any raw sockets listening on that same port will receive copies of the packets.