[Python] Client not sending messages to the UI via Unix Domain Socket in Chat Application

Discussão em 'Python' iniciado por Stack, Março 29, 2025.

  1. Stack

    Stack Membro Participativo

    Issue: Client not sending messages to the UI via Unix Domain Socket


    I'm working on a chat application that involves communication between a UI, a client, and a server. The client listens for incoming UDP messages and forwards them to the UI. The UI, on the other hand, should be able to send commands to the client, and the client should be able to send messages back to the UI. However, messages sent by the client to the UI are not being displayed in the UI, even though the client is successfully receiving messages from other clients.

    Setup:

    1. Unix Domain Socket: The communication between the client and the UI happens via a Unix domain socket.
    2. Client: The client listens for incoming UDP messages (such as MSG commands) and forwards them to the UI. The client also accepts commands from the UI (e.g., WHOIS, MSG).
    3. UI: The UI listens for incoming connections and commands from the client.
    Expected Behavior:

    • The UI should be able to receive messages from the client via the Unix domain socket.
    • The client should be able to send messages to the UI when it receives UDP messages (e.g., when a MSG command is received).
    Problem:

    • The UI is able to send commands to the client, and the client processes them correctly.
    • However, when the client receives a message (e.g., MSG), it attempts to send this message to the UI, but the UI does not display it.
    • The client code successfully prints that it's sending the message to the UI, but nothing shows up in the UI.
    What I've Tried:

    • The client sends messages to the UI using a Unix domain socket.
    • The UI is continuously listening for incoming messages, but it never displays anything when the client sends data.
    • The issue may be related to how the client and UI are interacting with the socket, particularly whether the UI is properly receiving and handling incoming messages.
    Code Snippets:

    Client:


    The client uses a Unix domain socket to send messages to the UI.

    import socket
    import os
    import random
    import threading
    import time

    ui_socket_path = "/tmp/chat_ui_socket" # Unix Socket for UI communication

    # Set up UDP Socket for communication with other clients
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    host = "0.0.0.0" # Listen on all network interfaces
    port = random.randint(5000, 65535) # Random port for the client
    udp_socket.bind((host, port))

    # Set up the UI Unix Domain Socket
    if os.path.exists(ui_socket_path):
    os.remove(ui_socket_path)

    ui_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    ui_socket.bind(ui_socket_path)
    ui_socket.listen(1)

    print(f"[Client started] Listening for UI commands and UDP on port {port}...")

    iam_responses = {}

    def send_message(target, message):
    """Send a message to a specific user."""
    msg = f"MSG {target} {message}"
    print(f"[Message sent] {msg}")
    udp_socket.sendto(msg.encode(), ("localhost", 12345)) # Change the target to the correct server/client

    def listen_for_messages():
    """Listen for incoming UDP messages and forward them to the UI."""
    while True:
    data, addr = udp_socket.recvfrom(1024)
    message = data.decode()
    print(f"[Received] {message}")

    if message.startswith("MSG "):
    msg_content = message[4:].strip() # Remove "MSG "
    formatted_message = f"[Message received] {msg_content}\n"

    # Forward the message to the UI
    try:
    ui_conn = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    ui_conn.connect(ui_socket_path) # Connect to UI
    ui_conn.sendall(formatted_message.encode()) # Send the message to UI
    ui_conn.close() # Close the connection after sending
    except ConnectionRefusedError:
    print("[Error] UI not connected, message could not be forwarded.")

    def handle_ui_commands():
    """Listen for commands from the UI."""
    while True:
    conn, _ = ui_socket.accept()
    with conn:
    while True:
    command = conn.recv(1024).decode().strip()
    if not command:
    break

    if command.startswith("MSG "):
    parts = command.split(" ", 2)
    if len(parts) == 3:
    send_message(parts[1], parts[2])
    conn.sendall(f"✅ Message to {parts[1]} sent: {parts[2]}\n".encode())
    else:
    conn.sendall(b"[Error] Unknown command\n")

    def join_network():
    """Join the network by sending a JOIN message."""
    join_message = f"JOIN Client {port}"
    udp_socket.sendto(join_message.encode(), ("localhost", 12345)) # Change target as needed
    print(f"[JOIN sent] {join_message}")

    # Start the client by joining the network
    join_network()

    # Start UI and message listeners in separate threads
    threading.Thread(target=handle_ui_commands, daemon=True).start()
    threading.Thread(target=listen_for_messages, daemon=True).start()

    # Keep the client running
    while True:
    time.sleep(1)

    UI:


    The UI listens for incoming connections and processes messages sent by the client.

    import socket
    import os

    ui_socket_path = "/tmp/chat_ui_socket" # Unix Socket path for communication

    def ui():
    """Simple terminal UI for the chat client."""
    print(" Chat-UI started! Use /help for commands.")

    # Create and bind the Unix socket for UI
    if os.path.exists(ui_socket_path):
    os.remove(ui_socket_path)

    ui_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    ui_socket.bind(ui_socket_path)
    ui_socket.listen(1) # Listen for incoming connections from client

    print("Waiting for client to connect...")

    conn, _ = ui_socket.accept() # Accept the connection from the client
    with conn:
    print("Client connected!")

    while True:
    # Read a message from the client
    message = conn.recv(1024).decode()
    if message:
    print(f"New message: {message}")
    else:
    print("Connection closed.")
    break

    # Handle user input for commands (like sending a message)
    user_input = input("> ")

    if user_input.lower() == "exit":
    print("Exiting...")
    break
    elif user_input.startswith("MSG "):
    conn.sendall(user_input.encode()) # Send the message to client
    else:
    print("Unknown command.")

    if __name__ == "__main__":
    ui()

    Additional Information:

    • The client successfully receives messages from other clients (via UDP) and processes them correctly.
    • The UI is able to send commands to the client via the Unix domain socket without issues.
    • The client prints debug information showing that it is attempting to send messages to the UI, but the UI does not display them.

    Continue reading...

Compartilhe esta Página