Reputation: 355
With Python, is it possible to send UDP data on local host and some port, then simultaneously inside same program, listen to different port on local host? I keep getting error 48'address already in use' and have tried using python's reuse address, although I'm pretty sure it won't work for this application anyways.
Background: I don't know anything about software development much less Python, this is just something that someone asked for at work.
I appreciate any help.
from threading import Thread
import time
import socket
HOST = 'localhost'
PORT = 5455
PORT1 = 5457
data1 = "1"
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST,PORT1))
a = 0
def myfunction(string, *args):
while 1:
cmd = int( raw_input("send message: ") )
if (cmd == 1):
s.sendto(data1, (HOST,PORT))
time.sleep(1)
def myfunction2(string, *args):
while 1:
print s.recv(30)
time.sleep(.5)
if __name__=='__main__':
try:
Thread(target=myfunction, args=(a, 1)).start()
Thread(target=myfunction2, args=(a, 1)).start()
except Exception, errtxt:
print errtxt
Upvotes: 4
Views: 6338
Reputation: 57408
Yes, it is. In any language. You are probably listening twice to the same port; TCP and UDP endpoints are characterized by the IP address and the port. "Address already in use" will only appear for a full match, same address and same port.
Also, verify that the listening port isn't already in use with netstat
.
UPDATE (thanks to l4mpi): you will get an "access denied" if you try to use a port below 1024 without having superuser privileges.
UPDATE
I have slightly modified your code; one of the problems you had was some confusion about sending and receiving sockets, which was the "client" function and which was the "server".
I have taken the liberty of querying for a message body instead of "1", but it is easy to put things back if necessary.
from threading import Thread
import time
import socket
CONN = ('localhost', 5455)
def fn_client(string, *args):
cs = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
cs.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
while 1:
cmd = int( raw_input("command (1 to send): ") )
if (cmd == 1):
data = raw_input("message to send: ")
cs.sendto(data, CONN)
time.sleep(1)
def fn_server(string, *args):
ss = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
ss.bind(CONN)
while 1:
print "Server received '%s'" % (ss.recv(30))
time.sleep(.5)
if __name__=='__main__':
a = 0
try:
Thread(target=fn_client, args=(a, 1)).start()
Thread(target=fn_server, args=(a, 1)).start()
except Exception, errtxt:
print errtxt
Upvotes: 5
Reputation: 32610
Your code works for me insofar that it doesn't produce Address already in use
.
But your threading code isn't too clean, KeyboardInterrupt
doesn't get handled in threads. This is a common problem with multithreading, see this answer or this recipe for an example on how to mitigate it.
This means you can't gracefully terminate your program by using CTRL-C
. Instead you probably had to resort to using something like kill [pid]
, maybe even with -9
? My guess is that you got leftover connections from previous runs of the program that caused Address already in use
. Use something like netstat -anp | grep 5457
to determine if there are still connections on that port.
Also see Doug Hellman's article for a good introduction to threading.
Upvotes: 1