Pythonメモ torinaブログ

このブログはDjangoとBootstrap4で作成されました
ソースコード

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

プログラミング関連 threadingモジュール
約306日前 2016年5月25日2:35
socketモジュールとthreadingモジュールを使い、マルチスレッドでCUIなチャットを作ります
サーバは接続があるたびにスレッド作成し、それぞれの接続先との処理を任せていきます
クライアントはサーバに接続後、input()でメッセージを送信するループをしつつ、メッセージ受信用のスレッドを作成しprintt()していきます
エラー処理が甘い部分が多いのですが、なんとか動いてくれるはずです。

server.py
import socket
import threading


HOST = ''
PORT = 9998
clients = []


def remove_conection(con, address):
    """クライアントと接続を切る"""

    print('[切断]{}'.format(address))
    con.close()
    clients.remove((con, address))


def server_start():
    """サーバをスタートする"""

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((HOST, PORT))
    sock.listen(10)

    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()


def handler(con, address):
    """クライアントからデータを受信する"""

    while True:
        try:
            data = con.recv(1024)
        except ConnectionResetError:
            remove_conection(con, address)
            break
        else:
            if not data:
                remove_conection(con, address)
                break
            else:
                print("[受信]{} - {}".format(address, data.decode("utf-8")))
                for c in clients:
                    c[0].sendto(data, c[1])


if __name__ == "__main__":
    server_start()




client.py
import socket
import threading


HOST = '127.0.0.1'
PORT = 9998


def input_msg_roop(sock):
    """メッセージ入力を促し、サーバに送信する"""

    while True:
        msg = input('>>>')
        if msg == 'exit':
            break
        elif msg:
            sock.send(msg.encode('utf-8'))


def client_start():
    """クライアントのスタート"""

    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:
        input_msg_roop(sock)
    finally:
        sock.close()


def handler(sock):
    """サーバからメッセージを受信し、表示する"""

    while True:
        data = sock.recv(1024)
        print("[受信]{}".format(data.decode("utf-8")))


if __name__ == "__main__":
    client_start()