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

Python Socket运行广播脚本报WinError 10048端口占用错误排查

问题原因
  • 报错直接诱因是Python模块导入的执行规则:当你在broadcast.py中执行from chatServer import broadcast时,Python会完整运行chatServer.py所有顶层作用域的代码,包括创建socket、绑定端口、启动监听、运行接收循环这整套服务端启动流程。
  • 此时你已经提前启动了一个chatServer服务端进程,192.168.1.109:42976这个套接字地址已经被原有进程占用,导入时触发的第二次服务端启动尝试再次绑定同个端口,就会抛出WinError 10048地址占用错误。
  • 就算绕过端口报错,当前实现逻辑也无法正常工作:独立启动的broadcast.py和正在运行的服务端是两个完全隔离的进程,导入拿到的broadcast函数操作的是新进程内空的clients列表,根本无法给已经连接到原有服务端的客户端发送消息。另外你当前调用broadcast时传入的是字符串类型,而socket的send方法要求传入字节类型,还会触发类型错误。
修复步骤
  1. 重构chatServer.py的代码结构,将服务端启动逻辑放到if __name__ == "__main__":判断块内,保证只有直接运行chatServer.py时才会启动服务,被其他脚本导入时不会执行端口绑定操作。重构后的chatServer.py代码参考如下:
import threading
import socket

# 公共配置、全局变量、工具函数保留在顶层
host = "192.168.1.109"
port = 42976
clients = []
nicknames = []

def broadcast(message):
    for client in clients:
        client.send(message)

def handle(client):
    while True:
        try:
            message = client.recv(1024)
            broadcast(message)
        except:
            index = clients.index(client)
            clients.remove(client)
            client.close()
            nickname = nicknames[index]
            broadcast('{} ha abbandonato!'.format(nickname).encode('utf-8'))
            print(f"{nickname} ha abbandonato.")
            nicknames.remove(nickname)
            break

def receive(server):
    while True:
        client, address = server.accept()
        print("Connesso con {}".format(str(address)))
        client.send('NICK'.encode('utf-8'))
        nickname = client.recv(1024).decode('utf-8')
        nicknames.append(nickname)
        clients.append(client)

        print("Il nickname è {}".format(nickname))
        if nickname == "Admin":
            broadcast("Il capo è entrato! Salutate l'Admin!".encode('utf-8'))
        else:
            broadcast("{} è entrato!".format(nickname).encode('utf-8'))
        client.send('Connesso al server!'.encode('utf-8'))

        thread = threading.Thread(target=handle, args=(client,))
        thread.start()

def server_command_input():
    # 单独线程读取服务端控制台输入,实现广播
    while True:
        content = input("Inserisci messaggio broadcast: ")
        if content.strip():
            broadcast(f"[Avviso server] {content}".encode('utf-8'))

if __name__ == "__main__":
    print(f'''Host: {host}
Porta: {port}''')
    server = socket.socket()
    # 开启端口复用,避免服务端临时重启时提示端口占用
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind((host, port))
    server.listen()
    # 启动控制台广播线程
    cmd_thread = threading.Thread(target=server_command_input, daemon=True)
    cmd_thread.start()
    receive(server)
  1. 放弃单独运行broadcast.py的实现思路:直接运行重构后的chatServer.py启动服务,服务端控制台会自动等待广播内容输入,输入内容后会直接广播给所有已连接的客户端,不需要额外启动第二个脚本,从根源上避免跨进程通信和端口冲突问题。

如果一定要保留独立广播脚本的形式,需要将广播脚本实现为特殊的管理员客户端,通过socket连接到正在运行的服务端,自定义通信协议标识广播指令,由服务端收到指令后完成广播转发,这种方案改动量较大,没有特殊需求不推荐使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:27:45