You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多线程套接字程序首个函数阻塞,无法同时收发的解决咨询

解决Python线程同时实现套接字监听与发送的问题

Hey there, let's fix your issue step by step—your core problem is a common gotcha with Python threading, and once we sort that out, we can tweak the rest to get things working smoothly.

核心错误:线程创建时的目标函数调用方式不对

Look at how you're creating your threads:

x = threading.Thread(target=listen())
y = threading.Thread(target=send())

When you write listen() with parentheses, you're immediately executing the function in the main thread before the thread even gets created. That's why your program gets stuck on s.accept()—the main thread is running listen() directly, and it never gets around to starting the send thread at all.

The fix here is simple: pass the function object instead of calling it. Remove the parentheses, and for the send thread, pass the required arguments properly:

x = threading.Thread(target=listen)
y = threading.Thread(target=send, args=("127.0.0.1", 30000))

修正send函数的未定义变量问题

Your send function has two undefined variables: target and self.port. Let's adjust it to accept the target address and port as parameters, plus tweak the exit logic to avoid killing the entire program:

def send(target_addr: str, port: int):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        try:
            s.connect((target_addr, port))
        except ConnectionRefusedError:
            print(f"Cannot reach host {target_addr}:{port}")
            return  # Use return instead of exit() to keep the listen thread running
        print("Connected successfully! Type your messages below:")
        while True:
            content = input("Message: ")
            if not content:  # Optional: allow empty input to exit the send thread
                print("Exiting send thread...")
                break
            try:
                s.sendall(content.encode())
            except ConnectionResetError:
                print("Connection has been interrupted.")
                break

修改后的完整代码

Here's the full corrected code that will run both listen and send threads simultaneously:

import socket
import threading

def listen():
    addr = socket.gethostbyname(socket.gethostname())
    port = 30000
    print(f"Listening for connections on {addr}:{port}")
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((addr, port))
        s.listen()
        conn, address = s.accept()
        with conn:
            client_addr, client_port = address
            print(f"Connected to {client_addr}:{client_port}")
            while True:
                try:
                    data = conn.recv(4096)
                    if not data:  # Detect if client closed the connection
                        print("Client disconnected.")
                        break
                    print(f"New message from {client_addr}: {data.decode()}")
                except ConnectionResetError:
                    print("Connection has been interrupted.")
                    break

def send(target_addr: str, port: int):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        try:
            s.connect((target_addr, port))
        except ConnectionRefusedError:
            print(f"Cannot reach host {target_addr}:{port}")
            return
        print("Connected successfully! Type your messages below (empty input to exit):")
        while True:
            content = input("Message: ")
            if not content:
                print("Exiting send thread...")
                break
            try:
                s.sendall(content.encode())
            except ConnectionResetError:
                print("Connection has been interrupted.")
                break

if __name__ == "__main__":
    # Start listen thread (no arguments needed)
    listen_thread = threading.Thread(target=listen)
    # Start send thread with target IP and port (adjust the IP to your target)
    send_thread = threading.Thread(target=send, args=("127.0.0.1", 30000))
    
    listen_thread.start()
    send_thread.start()
    
    # Optional: Wait for threads to finish so the main program doesn't exit immediately
    listen_thread.join()
    send_thread.join()

额外优化建议

  • Handle multiple connections: Right now, your listen function only accepts one connection. If you want to support multiple clients, spawn a new thread for each accepted connection:
    def handle_client(conn, address):
        client_addr, client_port = address
        print(f"Connected to {client_addr}:{client_port}")
        while True:
            try:
                data = conn.recv(4096)
                if not data:
                    print(f"Client {client_addr} disconnected.")
                    break
                print(f"New message from {client_addr}: {data.decode()}")
            except ConnectionResetError:
                print(f"Connection with {client_addr} interrupted.")
                break
    
    def listen():
        addr = socket.gethostbyname(socket.gethostname())
        port = 30000
        print(f"Listening for connections on {addr}:{port}")
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.bind((addr, port))
            s.listen()
            while True:
                conn, address = s.accept()
                threading.Thread(target=handle_client, args=(conn, address)).start()
    
  • Graceful exit: Add a threading.Event to signal threads to stop cleanly instead of relying on exceptions or empty input.

内容的提问来源于stack exchange,提问作者JohnDoe898989

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 08:12:41