67

I am trying to write a program to send UDP packets, as in https://wiki.python.org/moin/UdpCommunication The code appears to be in Python 2:

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))

If I put parenthesis around the printed stuff, it just prints it on the screen.

What do I need to do to make this work?

glglgl
  • 89,107
  • 13
  • 149
  • 217
user2059619
  • 814
  • 1
  • 6
  • 7
  • 1
    Are you running the example code to receive UDP packets? It won't appear to do anything (besides print to console) unless you've got something receiving the packets. – circuitBurn Sep 11 '13 at 14:34
  • 1
    Do you see network traffic in wireshark? – RickyA Sep 11 '13 at 14:35

5 Answers5

90

With Python3x, you need to convert your string to raw bytes. You would have to encode the string as bytes. Over the network you need to send bytes and not characters. You are right that this would work for Python 2x since in Python 2x, socket.sendto on a socket takes a "plain" string and not bytes. Try this:

print("UDP target IP:", UDP_IP)
print("UDP target port:", UDP_PORT)
print("message:", MESSAGE)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
sock.sendto(bytes(MESSAGE, "utf-8"), (UDP_IP, UDP_PORT))
Manoj Pandey
  • 4,528
  • 1
  • 17
  • 18
  • 1
    Thanks! I checked on wireshark, and it successfully sent a UDP packet. +1 Accepted answer. – user2059619 Sep 11 '13 at 19:47
  • 1
    this only works for messages that are text. Keep in mind you can transfer and receive arbitrary data over the network with these functions so you cannot always assume decode/encode as utf8 will make sense. – user2957811 Mar 19 '18 at 21:56
10

Your code works as is for me. I'm verifying this by using netcat on Linux.

Using netcat, I can do nc -ul 127.0.0.1 5005 which will listen for packets at:

  • IP: 127.0.0.1
  • Port: 5005
  • Protocol: UDP

That being said, here's the output that I see when I run your script, while having netcat running.

[9:34am][wlynch@watermelon ~] nc -ul 127.0.0.1 5005
Hello, World!
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
4

Manoj answer above is correct, but another option is to use MESSAGE.encode() or encode('utf-8') to convert to bytes. bytes and encode are mostly the same, encode is compatible with python 2. see here for more

full code:

import socket

UDP_IP = "127.0.0.1"
UDP_PORT = 5005
MESSAGE = "Hello, World!"

print("UDP target IP: %s" % UDP_IP)
print("UDP target port: %s" % UDP_PORT)
print("message: %s" % MESSAGE)

sock = socket.socket(socket.AF_INET, # Internet
                     socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE.encode(), (UDP_IP, UDP_PORT))
ng10
  • 1,660
  • 1
  • 15
  • 19
2

If you are running python 3 then you need to change the print statements to print functions, i.e. put things in brackets () after print statements.

The only thing that you will see the above do is the prints unless you have something listening on 127.0.0.1 port 5005 as you are sending a packet not receiving it - so you need to implement and start the other part of the example in another console window first so it is waiting for the message.

Steve Barnes
  • 27,618
  • 6
  • 63
  • 73
0

Here is a complete example that has been tested with Python 2.7.5 on CentOS 7.

#!/usr/bin/python

import sys, socket

def main(args):
    ip = args[1]
    port = int(args[2])
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    file = 'sample.csv'

    fp = open(file, 'r')
    for line in fp:
        sock.sendto(line.encode('utf-8'), (ip, port))
    fp.close()

main(sys.argv)

The program reads a file, sample.csv from the current directory and sends each line in a separate UDP packet. If the program it were saved in a file named send-udp then one could run it by doing something like:

$ python send-udp 192.168.1.2 30088
pdp
  • 4,117
  • 1
  • 17
  • 20