1. 程式人生 > 實用技巧 >python多執行緒一對一全雙工通訊

python多執行緒一對一全雙工通訊

一共兩個客戶端,服務端為每個客戶端開啟兩個執行緒(比較浪費)

服務端程式碼
from socket import *
from threading import Thread
from queue import Queue
from time import ctime


HOST = ""
PORT = 12345
ADDR = (HOST, PORT)
conns = []
queues = []
client_dict = {}


class Receive(Thread):
    def __init__(self, conn, q):
        super().__init__()
        self.conn = conn
        self.q = q

    def run(self):
        if len(conns) == 1:
            self.conn.send(bytes("對方當前不線上,請留言:", encoding='utf8'))
        while True:
            try:
                data = self.conn.recv(1024)
                if data.decode() == "quit":
                    self.conn.close()
                    conns.remove(self.conn)
                    for i in client_dict[self.conn]:
                        queues.append(i)
                    self.q.put("對方已下線,請留言:".encode())
                    break
                else:
                    self.q.put(data)
            except ConnectionResetError:
                self.conn.close()
                conns.remove(self.conn)
                self.q.put("對方已下線,請留言".encode())
                for i in client_dict[self.conn]:
                    queues.append(i)
                break


class Send(Thread):
    def __init__(self, conn, q):
        super().__init__()
        self.conn = conn
        self.q = q

    def run(self):
        while True:
            try:
                if self.conn in conns:
                    data = self.q.get()
                    self.conn.send(data)
                else:
                    self.conn.close()
                    break
            except error:
                break


def main():
    server = socket(AF_INET, SOCK_STREAM)
    server.bind(ADDR)
    server.listen(2)
    while True:
        client, address = server.accept()
        print(f"[{ctime()}]connected from {address}")
        if len(conns) == 1:
            conns[0].send(f"[{ctime()}]對方已上線".encode())
        conns.append(client)
        if len(conns) == 1:
            que1 = Queue(10)
            que2 = Queue(10)
            queues.append(que1)
            queues.append(que2)
        else:
            que1 = queues.pop()
            que2 = queues.pop()
        client_dict[client] = [que2, que1]
        Receive(client, que1).start()
        Send(client, que2).start()


if __name__ == '__main__':
    main()

客戶端
from socket import *
from threading import Thread
ADDR = 'localhost'
port = 12345


client = socket()
client.connect((ADDR, port))
mes = client.recv(1024)
print(mes.decode())


def send_msg():
    while True:
        data = input(">")
        if data:
            client.send(bytes(f"{data}", encoding='utf8'))


def recv_msg():
    while True:
        data = client.recv(1024)
        if data:
            print(data.decode())


if __name__ == '__main__':
    s = Thread(target=send_msg)
    r = Thread(target=recv_msg)
    s.start()
    r.start()
    s.join()
    r.join()