Using One Socket In Udp Chat Using Threading
Solution 1:
Congrats on your introduction to Python! It looks like you're using Python 3, and in future questions it's helpful if you are explicit about which version you're using because there are minor but program-breaking incompatibilities in some code (including this code!).
I found a few errors in your program:
The most major issue - as Trevor Barnwell says, you're not calling
threading.Thread
quite correctly. Thetarget=
argument needs to be a callable object (i.e. function), but in this case it should just be a reference to the function. If you add brackets to the function,self.create_socket(host, port)
as you have above, it actually runs the function immediately. As Trevor explained, yourSending.send()
method was called early, but additionally there was a similar bug inReceiving
. Because Receiving.create_socket() creates an infinite loop, it never returns program execution. While the console output looks correct to the user, the actual program execution has never made it to running the listener in a separate thread.bytearray.extend()
takes an iterable of ints, what you're passing right now is a tuple of byte objects.In
Sending.send()
you callself.sock
, but you never assignself.sock
a value, so it fails.Sending.run()
only runsSending.send()
one time. After completing input for the user, it immediately exits, because the program has finished.
If you're looking for an in-depth, project based introduction to Python appropriate for an experienced programmer (including an exercise very similar to this question on basic sockets, and another on threading), I highly recommend you check out Wesley Chun's "Core Python Applications Programming". The most recent edition (3rd) has a lot of Python 2 code, but it's easily portable to Python 3 with some minor work on the reader's part.
I tried to modify your code as little as possible to get it working, here it is:
import socket
import threading
import logging
import time
classSending():
def__init__(self, name, tHost, tPort, target):
self.name = name
self.host = tHost
self.port = tPort
self.target_port = target
self.sock = self.create_socket()
defcreate_socket(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((self.host, self.port))
return sock
defset_name(self, name):
self.name = name
defsend_loop(self):
whileTrue:
logging.debug('Starting send run')
message = input('Enter message: ')
data = bytearray()
data.extend(message.encode('utf-8'))
self.sock.sendto(bytearray(data), (self.host, self.target_port))
defrun(self):
th2 = threading.Thread(name='send', target=self.send_loop)
th2.start()
classReceiving():
def__init__(self, host, port):
self.host = host
self.port = port
defcreate_socket(self):
logging.debug('Starting socket')
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((self.host, self.port))
print ('socket ready')
time.sleep(5)
whileTrue:
data, addr = sock.recvfrom(1500)
print('\nPrijata:' + data.decode('utf-8') + str(addr))
defrun(self):
th1 = threading.Thread(name='rec', target=self.create_socket)
print("Made it here")
th1.daemon = True
th1.start()
returnif __name__ == '__main__':
print('running')
rec = Receiving('localhost', 8000)
send = Sending('username', 'localhost', 8001, 8000)
rec.run()
send.run()
Solution 2:
The threads are not blocking each other. send
is called before a thread is even created.
th2 = threading.Thread(name = 'send', target=self.send('username', 'localhost', 8001, 1, 1400))
This line makes a call to send at:
self.send('username', 'localhost', 8001, 1, 1400)
I think you meant to do this:
th2 = threading.Thread(
target=self.send
args=('username', 'localhost', 8001, 1, 1400))
That way a thread will start that calls send on the next line.
Two other things:
- You will want to loop in your functions because the thread terminates once the function does.
- I think you mean
raw_input
instead ofinput
Post a Comment for "Using One Socket In Udp Chat Using Threading"