Python Socket报错OSError: [WinError 10038] 问题求助
Kivy+Socket聊天App发送消息报错WinError 10038的解决方案
问题描述
使用Kivy和Socket开发可在PC与Android运行的聊天App,输入用户名连接服务器后尝试发送消息,触发如下错误:
File "c:\Users\adebu\Documents\Andriod chat app\webchat.kv", line 82, in <module> on_press: root.send_message() File "c:\Users\adebu\Documents\Andriod chat app\main.py", line 20, in send_message client.send(cmessage.encode("utf-8")) OSError: [WinError 10038] An operation was attempted on something that is not a socket"
相关代码如下:
客户端代码
import kivy from kivy.app import App from kivy.uix.boxlayout import BoxLayout import socket import threading kivy.require("1.9.0") client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) class MyRoot(BoxLayout): def __int__(self): super(MyRoot, self).__init__() def send_message(self): cmessage = (f"{self.nickname_text.text}: {self.message_text.text}") client.send(cmessage.encode("utf-8")) def connect_to_server(self): if self.nickname_text != "": client.connect((self.ip_text.text, 9999)) message = client.recv(1024).decode('utf-8') if message == 'NICK': client.send(self.nickname_text.text.encode('utf-8')) self.send_btn.disable = True self.message_text.disable = True self.connect_btn.disable = True self.ip_text.disable = True self.make_invisible(self.connection_grid) self.make_invisible(self.connect_btn) thread = threading.Thread(target=self.receive) thread.start() def make_invisible(self, widget): widget.visible = False widget.size_hint_x = None widget.size_hint_y = None widget.height = 0 widget.width = 0 widget.txt = "" widget.opacity = 0 def receive(self): stop = False while not stop: try: message = client.recv(1024).decode('utf-8') self.chat_text.text += message + "\n" except: print("ERROR") client.close() stop = True class WebChat(App): def build(self): return MyRoot() webChat = WebChat() webChat.run()
Kivy布局文件
<MyRoot> ip_text: ip_text nickname_text: nickname_text connect_btn: connect_btn chat_text: chat_text message_text: message_text send_btn: send_btn connection_grid: connection_grid orientation: 'vertical' GridLayout: id: connection_grid rows: 1 cols: 2 padding: 10 spacing: 10 height: 125 size_hint: (1, None) BoxLayout: orientation: 'vertical' Label: text: "Server IP" font_size: 42 color: 180, 100, 50, 1 TextInput: id: ip_text size_hint: (1, None) height: 50 font_size: 36 BoxLayout: orientation: 'vertical' Label: text: "Nickname" font_size: 42 color: 180, 100, 50, 1 TextInput: id: nickname_text size_hint: (1, None) height: 50 font_size: 36 Button: id:connect_btn text: "Connect" font_size: 32 size: 100, 50 size_hint: (1, None) height: 70 on_press: root.connect_to_server() color: 180, 100, 50, 1 Label: text: "Chat History" font_size: 42 height: 50 size_hint: (1, None) color: 23, 0, 0, 1 TextInput: id: chat_text size_hint: (1, None) height: 450 multiline: True font_size: 36 readonly: True disabled: True Label: text: "Your Message" font_size: 42 height: 50 size_hint: (1, None) color: 23, 0, 0, 1 TextInput: id: message_text font_size: 36 disabled: True Button: id: send_btn text: "Send" font_size: 32 size: 100, 50 on_press: root.send_message() disabled: True
服务端代码
import socket import threading HOST = "localhost" PORT = 9999 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((HOST, PORT)) server.listen() clients = [] nicknames = [] def broadcast(message): for client in clients: client.send(message) def handle_connection(client): stop = False while not stop: try: message = client.recv(1024) broadcast(message) except: index = client.index(client) client.remove(client) nickname = nicknames[index] nicknames.remove(nickname) broadcast(f"{nickname} left the chat!".encode('utf-8')) stop = True def main(): print("server is online...") while True: client, addr = server.accept() print(f"Connected to {addr}") client.send("NICK".encode('utf-8')) nickname = client.recv(1024).decode('utf-8') nicknames.append(nickname) clients.append(client) print(f"Nickname is {nickname}") broadcast(f"{nickname} joined the chat!".encode('utf-8')) client.send("You are now connected!".encode('utf-8')) thread = threading.Thread(target=handle_connection, args=(client,)) thread.start() if __name__ == '__main__': main()
错误原因及修复步骤
1. 客户端类构造函数拼写错误
MyRoot类的构造函数写成了__int__,正确应为__init__,这会导致Kivy控件初始化异常,间接影响套接字操作的正确性。
修复代码:
# 原代码 def __int__(self): super(MyRoot, self).__init__() # 修改为 def __init__(self): super(MyRoot, self).__init__()
2. 连接成功后错误禁用发送控件
connect_to_server方法中,连接成功后错误设置了发送按钮和消息输入框为禁用状态,且Kivy中控件的禁用属性是disabled而非disable。
修复代码:
# 原代码 self.send_btn.disable = True self.message_text.disable = True # 修改为 self.send_btn.disabled = False self.message_text.disabled = False
3. 服务端索引获取逻辑错误
handle_connection函数中,获取客户端索引时错误使用了client.index(client),正确应从clients列表中查找索引,同时移除客户端时也需操作clients列表。
修复代码:
# 原代码 index = client.index(client) client.remove(client) # 修改为 index = clients.index(client) clients.remove(client)
4. 客户端昵称判断逻辑错误
connect_to_server方法中,判断昵称是否为空时直接比较控件对象而非其text属性,导致判断逻辑失效。
修复代码:
# 原代码 if self.nickname_text != "": # 修改为 if self.nickname_text.text.strip():
5. Kivy控件属性错误
make_invisible方法中使用了不存在的visible和txt属性,Kivy控件无此类属性,需删除无效代码。
修复代码:
# 原代码 def make_invisible(self, widget): widget.visible = False widget.size_hint_x = None widget.size_hint_y = None widget.height = 0 widget.width = 0 widget.txt = "" widget.opacity = 0 # 修改为 def make_invisible(self, widget): widget.size_hint_x = None widget.size_hint_y = None widget.height = 0 widget.width = 0 widget.opacity = 0
验证修复
完成上述修改后,重启服务端和客户端,输入服务器IP和昵称连接,即可正常发送消息,不会再触发WinError 10038错误。
内容的提问来源于stack exchange,提问作者user20546889
相关产品推荐
相关产品推荐

