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

Python Socket报错WinError10057:多次发送消息失败求修复方案

解决OSError: [WinError 10057] 多消息收发失败问题

问题现象

服务器与客户端可正常收发第一条消息,但尝试发送多条消息时触发以下错误:

OSError: [WinError 10057] A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied.

原服务器代码

import socket
import threading
import time
from tkinter import *


#functions
def t_recv():
    r = threading.Thread(target=recv)
    r.start()

def recv():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as listensocket:
        port = 5354
        maxconnections = 9
        ip = socket.gethostbyname(socket.gethostname())
        print(ip)
        server = (ip, port)
        FORMAT = 'utf-8'

        listensocket.bind((server))
        listensocket.listen(maxconnections)
        (clientsocket, address) = listensocket.accept()
        msg = f'\[ALERT\] {address} has joined the chat.'
        lstbox.insert(0, msg)

    while True:
        sendermessage = clientsocket.recv(1024).decode(FORMAT)
        if not sendermessage == "":
            time.sleep(3)
            lstbox.insert(0, 'Client: ' +sendermessage)

def t_sendmsg():
    s = threading.Thread(target=sendmsg)
    s.start()

at = 0

def sendmsg():
    global at
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as g:
        hostname = 'Lenovo-PC'
        port = 5986

        if at==0:
            g.connect((hostname, port))
            msg = messagebox.get()
            lstbox.insert(0, 'You: ' +msg)
            g.send(msg.encode())
            at += 1

        else:
            msg = messagebox.get()
            lstbox.insert(0, 'You: ' +msg)
            g.send(msg.encode())      

原客户端代码

import socket
import time
import threading
from tkinter import *

#functions
def t_recv():
    r = threading.Thread(target=recv)
    r.start()

def recv():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as listensocket:
        port = 5986
        maxconnections = 9
        ip = socket.gethostname()
        print(ip)
        FORMAT = 'utf-8'
        host = 'MY_IP'    # My actual ip is there in the code

        listensocket.bind((host, port))
        listensocket.listen(maxconnections)
        (clientsocket, address) = listensocket.accept()


        while True:
            sendermessage = clientsocket.recv(1024).decode(FORMAT)
            if not sendermessage == "":                 
                time.sleep(3)                 
                lstbox.insert(0, 'Server: ' +sendermessage)

def t_sendmsg():
    s = threading.Thread(target=sendmsg)
    s.start()

at = 0

def sendmsg():
    global at
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as g:
        hostname = 'Lenovo-PC'
        port = 5354

        if at==0:
            g.connect((hostname, port))
            msg = messagebox.get()
            lstbox.insert(0, 'You: ' +msg)
            g.send(msg.encode())
            at += 1

        else:
            msg = messagebox.get()
            lstbox.insert(0, 'You: ' +msg)
            g.send(msg.encode())        

问题原因与修复方案

核心问题分析

  1. Socket作用域错误:recv函数中用with语句创建监听socket,代码块结束后socket会被自动关闭,但后续while循环仍在使用clientsocket,导致连接异常。
  2. 发送socket复用失败:sendmsg函数每次调用都会新建socket,首次发送后with代码块关闭socket,后续发送时使用的是未连接的新socket,触发报错。

修改后的服务器代码

import socket
import threading
import time
from tkinter import *

# 全局存储客户端连接socket
client_socket = None
FORMAT = 'utf-8'

def t_recv():
    r = threading.Thread(target=recv)
    r.start()

def recv():
    global client_socket
    # 移除with语句,保持socket持续打开
    listensocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    port = 5354
    maxconnections = 9
    ip = socket.gethostbyname(socket.gethostname())
    print(ip)
    server = (ip, port)

    listensocket.bind(server)
    listensocket.listen(maxconnections)
    client_socket, address = listensocket.accept()
    msg = f'[ALERT] {address} has joined the chat.'
    lstbox.insert(0, msg)

    while True:
        try:
            sendermessage = client_socket.recv(1024).decode(FORMAT)
            if sendermessage:
                time.sleep(3)
                lstbox.insert(0, 'Client: ' + sendermessage)
            else:
                lstbox.insert(0, '[ALERT] Client disconnected.')
                break
        except Exception as e:
            lstbox.insert(0, f'[ERROR] {str(e)}')
            break
    # 连接断开后关闭socket
    client_socket.close()
    listensocket.close()

def t_sendmsg():
    s = threading.Thread(target=sendmsg)
    s.start()

def sendmsg():
    global client_socket
    if not client_socket:
        lstbox.insert(0, '[ERROR] No client connected yet.')
        return
    msg = messagebox.get()
    if not msg:
        return
    lstbox.insert(0, 'You: ' + msg)
    try:
        client_socket.send(msg.encode(FORMAT))
    except Exception as e:
        lstbox.insert(0, f'[ERROR] Failed to send message: {str(e)}')

# 补充Tkinter UI初始化(原代码缺失部分)
root = Tk()
messagebox = Entry(root)
messagebox.pack()
lstbox = Listbox(root)
lstbox.pack()
send_btn = Button(root, text="Send", command=t_sendmsg)
send_btn.pack()
t_recv()
root.mainloop()

修改后的客户端代码

import socket
import time
import threading
from tkinter import *

# 全局存储与服务器的连接socket
server_socket = None
FORMAT = 'utf-8'

def t_recv():
    r = threading.Thread(target=recv)
    r.start()

def recv():
    global server_socket
    # 移除with语句,保持socket持续打开
    listensocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    port = 5986
    maxconnections = 9
    host = 'MY_IP'  # 替换为实际IP

    listensocket.bind((host, port))
    listensocket.listen(maxconnections)
    server_socket, address = listensocket.accept()

    while True:
        try:
            sendermessage = server_socket.recv(1024).decode(FORMAT)
            if sendermessage:
                time.sleep(3)
                lstbox.insert(0, 'Server: ' + sendermessage)
            else:
                lstbox.insert(0, '[ALERT] Server disconnected.')
                break
        except Exception as e:
            lstbox.insert(0, f'[ERROR] {str(e)}')
            break
    # 连接断开后关闭socket
    server_socket.close()
    listensocket.close()

def t_sendmsg():
    s = threading.Thread(target=sendmsg)
    s.start()

def sendmsg():
    global server_socket
    if not server_socket:
        lstbox.insert(0, '[ERROR] Not connected to server yet.')
        return
    msg = messagebox.get()
    if not msg:
        return
    lstbox.insert(0, 'You: ' + msg)
    try:
        server_socket.send(msg.encode(FORMAT))
    except Exception as e:
        lstbox.insert(0, f'[ERROR] Failed to send message: {str(e)}')

# 补充Tkinter UI初始化(原代码缺失部分)
root = Tk()
messagebox = Entry(root)
messagebox.pack()
lstbox = Listbox(root)
lstbox.pack()
send_btn = Button(root, text="Send", command=t_sendmsg)
send_btn.pack()
t_recv()
root.mainloop()

关键修改点

  • 移除with语句创建socket,避免代码块结束后自动关闭连接。
  • 用全局变量存储已建立的连接socket,让收发函数共用同一个连接,无需重复创建。
  • 增加异常处理,捕获连接断开、发送失败等场景,提升程序稳定性。
  • 删除无用的at变量,通过全局socket的存在性判断连接状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:55:23