torinaブログ

DjangoとBootstrap4で作成したブログ
Python, Django, Kivy, Bootstrap, Apache等のメモです
ソースコード

Python、マルチスレッドを使い簡易チャット

Python Python並行並列処理
2016年5月25日2:35


socketモジュールとthreadingモジュールを使い、マルチスレッドでCUIなチャットを作ります
サーバは接続があるたびにスレッド作成し、それぞれの接続先との処理を任せていきます
クライアントはサーバに接続後、input()でメッセージを送信するループをしつつ、メッセージ受信用のスレッドを作成しprintt()していきます

server.py
import socket
import threading
 
 
HOST = ''
PORT = 9998
clients = []
 
 
def server_start():
 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((HOST, PORT))
    sock.listen(10)
 
    try:
        while True:
            con, address = sock.accept()
            print("{}から新しい接続".format(address))
            clients.append((con, address))
            handle_thread = threading.Thread(target=handler,
                                             args=(con, address),
                                             daemon=True)
            handle_thread.start()
 
    finally:
        sock.close()
 
 
def handler(con, address):
    try:
        while True:
            data = con.recv(1024)
            if not data:
                print("{}の接続が切れました".format(address))
                break
            else:
                print("{}からメッセージ→{}".format(address, data.decode("utf-8")))
                for c in clients:
                    c[0].sendto(data, c[1])
 
    except ConnectionError:
        print("{}の接続が切れました".format(address))
    finally:
        con.close()
        clients.remove((con, address))
 
if __name__ == "__main__":
    server_start()



client.py
import socket
import threading
 
 
HOST = '127.0.0.1'
PORT = 9998
is_close = False
 
 
def clients_start():
    global is_close
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((HOST, PORT))
    handle_thread = threading.Thread(target=handler, args=(sock,), daemon=True)
    handle_thread.start()
 
    try:
        while not is_close:
            msg = str(input(">>>"))
            if msg == "exit":
                print("終了します")
                break
            else:
                sock.send(msg.encode("utf-8"))
    except ConnectionError:
        print("サーバーの接続が切れました")
    finally:
        if not is_close:
            sock.close()
            is_close = True
 
 
def handler(sock):
    global is_close
    try:
        while not is_close:
            data = sock.recv(1024)
            if not data:
                print("サーバーの接続が切れました")
                break
            else:
                print("メッセージ受信→{}".format(data.decode("utf-8")))
    except ConnectionError:
        print("サーバーの接続が切れました")
    finally:
        if not is_close:
            sock.close()
            is_close = True
 
if __name__ == "__main__":
    clients_start()