Python: synchronizing input and output between threads

I am currently trying to execute a small socket project in Python, a dual user chat system.

import socket
import threading

#Callback. Print doesn't work across threads
def data_recieved(data):
    print data

#Thread class to gather input
class socket_read(threading.Thread):
    sock = object
    def __init__(self, sock):
        threading.Thread.__init__(self)
        self.sock = sock
    def run(self):
        while True:
            data = self.sock.recv(1000)
            if (data == "\quitting\\"):
                return
            data_recieved(self.sock.recv(1000))

####################################################################################
server = False
uname = input("What your username: ")
print "Now for the technical info..."
port = input("What port do I connect to ['any' if first]: ")
#This is the first client. Let it get an available port
if (port == "any"):
    server = True
    port = 9999
    err = True
    while err == True:
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.bind(('', port))
            err = False
        except:
            err = True
        sock.close()

    print "Bound to port #" + str(port)
    print "Waiting for client..."

    sock.listen(1)
    (channel, info) = sock.accept()
else:
    #This is the client. Just bind it tho a predisposed port
    host = input("What the IP of the other client: ")
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host, int(port)))

msg = ""
if (server == True):
    #Use the connection from accept
    reader = socket_read(channel)
else:
    #Use the actual socket
    reader = socket_read(sock)
reader.start()
while msg != 'quit':
    #Get the message...
    msg = uname + ": " + input("Message: ")
    try:
        #And send it
        if (server == True):
            #Use the connection from accept
            channel.send(msg)
        else:
            #Use direct socket
            sock.send(msg)
    except:
        break
reader.join()
channel.send("\quitting\\")
sock.close()

(I hope the comments help)

In any case, causing simultaneous data input and receiving another socket message, I have a slight synchronization problem. I can connect, but when I receive a message, it does not cancel the input statement.

In other words, when I get a message, he talks about it

Message: user: I got a message
#Flashing cursor here 

So it does not cancel the input statement.

In addition, I receive only every message.

Any suggestions?

+3
source share
2 answers

, / . UI (curses, wxPython, pyqt) . () , .

, , ( ), , !

+1

, , MAGICAL ( , Linux).

, :

import socket
import threading

def msg_loop(socket):
    msg = ""
    if (server == True):
        reader = socket_read(channel)
    else:
        reader = socket_read(sock)
    reader.start()
    while msg != 'quit':
        msg = uname + " said : " + input("Message: ")
        print ""
        try:
            if (server == True):
                channel.send('null')
                channel.send(msg)
            else:
                sock.send('null')
                sock.send(msg)
        except:
            break

def data_recieved(data, socket):
    print "Hold on...\n\n" + data + "\n"
    msg_loop(socket)

class socket_read(threading.Thread):
    sock = object
    def __init__(self, sock):
        threading.Thread.__init__(self)
        self.sock = sock
    def run(self):
        while True:
            data = self.sock.recv(1000)
            if (data == "\quitting\\" or data == ''):
                return
            data_recieved(self.sock.recv(1000), self.sock)

####################################################################################
server = False
uname = str(input("What your username: "))
print "Now for the technical stuff..."
port = input("What port do I connect to ['any' if first]: ")
if (port == "any"):
    server = True
    port = 9999
    err = True
    while err == True:
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.bind(('', port))
            err = False
        except:
            print "Socket #" + str(port) + " failed"
            err = True
            sock.close()
            port -= 1

    print "Bound to port #" + str(port)
    print "Waiting for client..."

    sock.listen(1)
    (channel, info) = sock.accept()
else:
    host = input("What the IP of the other client: ")
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host, int(port)))

if (server == True):
    msg_loop(channel)
else:
    msg_loop(sock)

reader.join()
channel.send("\quitting\\")
sock.close()

, .

, , " ".

, data_recieved, .

( , Windows. , , -, Python . Linux-)

+1

Source: https://habr.com/ru/post/1726245/


All Articles