1
1

TCPを使ったチャットアプリの作り方

Posted at

TCPチャットサーバー

import socket
import threading

def client_thread(conn, client_address, rooms, clients):
    try:
        while True:
            data = conn.recv(1024).decode('utf-8')
            if not data:
                break  # クライアントが切断した場合
            
            command, room_name, message = data.split(',', 2)

            if command == 'JOIN':
                rooms[room_name].add(conn)
                clients[conn] = room_name
                print(f"{client_address} joined {room_name}")

            elif command == 'LEAVE':
                rooms[room_name].remove(conn)
                del clients[conn]
                conn.close()
                print(f"{client_address} left {room_name}")
                break

            elif command == 'MSG':
                for client in rooms[room_name]:
                    if client != conn:
                        client.sendall(f"{client_address}: {message}".encode('utf-8'))

    except Exception as e:
        print(f"Error: {str(e)}")
    finally:
        conn.close()

def main():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_address = '0.0.0.0'
    server_port = 9001
    server_socket.bind((server_address, server_port))
    server_socket.listen()

    rooms = {}  # チャットルームとクライアントの管理
    clients = {}  # クライアントとその現在のルームの追跡

    print(f"Server started on {server_address} port {server_port}")

    while True:
        conn, addr = server_socket.accept()
        print(f"Connection from {addr}")
        threading.Thread(target=client_thread, args=(conn, addr, rooms, clients)).start()

if __name__ == "__main__":
    main()

TCPチャットクライアント

import socket

def main():
    host = 'localhost'
    port = 9001

    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        sock.connect((host, port))
        print("Connected to the server.")

        while True:
            username = input("Enter your username: ")
            command = input("Enter command (JOIN, LEAVE, MSG): ")
            room_name = input("Enter room name: ")
            message = input("Enter message: ")
            full_message = f"{command},{room_name},{username}: {message}"
            sock.sendall(full_message.encode('utf-8'))

            if command == "LEAVE":
                break

if __name__ == "__main__":
    main()

補足説明

  • サーバー:

    • TCPソケットを作成し、接続を待ち受けます。
    • クライアントからの接続ごとにスレッドを生成し、専用の関数で通信を処理します。
    • JOIN, LEAVE, MSG コマンドを処理し、対応するチャットルームにメッセージを配信します。
  • クライアント:

    • サーバーに接続し、コマンド(JOIN、LEAVE、MSG)を入力してサーバーに送信します。
    • ユーザー名とメッセージを入力し、適切なフォーマットでサーバーに送信します。
    • LEAVEコマンドでチャットを終了し、接続を閉じます。
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1