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

Python Socket服务器触发WinError 10038,无法持续监听新连接求助

问题:Socket服务器处理单次请求后触发WinError 10038错误

我开发了一个基于Python Socket的服务器,集成SQLite数据库、人脸识别功能,实现用户登录与注册服务。目前服务器可处理单次客户端请求,但处理完成后会触发[WinError 10038]错误,无法继续等待新用户连接。

服务器代码

import sqlite3
import socket
import re
import face_recognition
import os, sys
import cv2
import numpy as np
import math
from recognition import FaceRecognizer
from SalaryDemo import Salary
from Camera import SignUpCamera


def main():
    # Connect to the SQLite database
    conn = sqlite3.connect('users.db')
    cursor = conn.cursor()
    cursor.execute("PRAGMA table_info('users')")
    result = cursor.fetchone()

    if not result:
        # If the 'users' table does not exist, create it
        cursor.execute('''CREATE TABLE users (id INTEGER PRIMARY KEY,
                                              username TEXT,
                                              password TEXT)''')
        cursor.execute("ALTER TABLE users ADD COLUMN user_data TEXT")

    
    # Set up the server
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('localhost', 8080))
    server.listen()
    open = True
    # Wait for incoming connections
    client, addr = server.accept()
    print(f'Connected by {addr}')
    while True:
    
        # Receive login/sign-up data from the client
        data = client.recv(1024)
        action, username, password = data.decode().split(':')
    
        if action == 'login':
            recognizer = FaceRecognizer()
            recognizer.load_faces("faces")
            if recognizer.recognize_face(username):
                cursor.execute('SELECT * FROM users WHERE username = ? AND password = ?', (username, password))
                result = cursor.fetchone()
            else:
                print(f"{username} not matched!")
                result = None
            
            if result:
                # If the login is successful, send the user's data back to the client
                user_data = f'{result[0]}:{result[1]}:{result[2]}'
                msg_to_client = "welcome " + username
                client.send(msg_to_client.encode())
                sl = Salary()
                sl.getSallary(username)                
            else:
                # If the login is unsuccessful, send an error message back to the client
                client.send('Invalid login'.encode())
    
        elif action == 'signup':
            cm = SignUpCamera()
            # Check if the password is strong enough
            if not re.search(r'[A-Z]', password) or not re.search(r'[a-z]', password) or not re.search(r'[0-9]', password):
                client.send('Password is not strong enough'.encode())
            else:
                # Check if the username is already in use
                cursor.execute('SELECT * FROM users WHERE username = ?', (username,))
                result = cursor.fetchone()

                if result:
                    # If the username is already in use, send an error message back to the client
                    client.send('Username already in use'.encode())
                else:
                    # If the username is available, insert a new row into the 'users' table
                    cursor.execute("INSERT INTO users (username, password, user_data) VALUES (?, ?, ? || '.jpg')", (username, password, username.lower()))
                    conn.commit()
                    cm.main(username)
                    client.send('Sign-up successful'.encode())
    
        client.close()


if __name__ == "__main__":
    main()

报错信息

Message=[WinError 10038] An operation was attempted on something that is not a socket
Source=C:\Users\Bar12\source\repos\final-project-afek-and-liam-authentication_client_server\ServerSideProject\ServerSideProject\ServerSideProject.py
StackTrace:
File "C:\Users\Bar12\source\repos\final-project-afek-and-liam-authentication_client_server\ServerSideProject\ServerSideProject\ServerSideProject.py", line 89, in <module>
    main()

问题分析与修复方案

问题根源

  1. 客户端Socket提前关闭:client.close()被放在了while True循环内部,处理完一次请求就关闭了客户端连接,但循环还会继续执行client.recv(),此时client已经不是有效的Socket对象,触发WinError 10038。
  2. 仅接受一次客户端连接:server.accept()只被调用了一次,服务器只能处理第一个客户端的请求,无法接收后续新的客户端连接。

修改后的代码

import sqlite3
import socket
import re
import face_recognition
import os, sys
import cv2
import numpy as np
import math
from recognition import FaceRecognizer
from SalaryDemo import Salary
from Camera import SignUpCamera


def main():
    # Connect to the SQLite database
    conn = sqlite3.connect('users.db')
    cursor = conn.cursor()
    cursor.execute("PRAGMA table_info('users')")
    result = cursor.fetchone()

    if not result:
        # If the 'users' table does not exist, create it
        cursor.execute('''CREATE TABLE users (id INTEGER PRIMARY KEY,
                                              username TEXT,
                                              password TEXT)''')
        cursor.execute("ALTER TABLE users ADD COLUMN user_data TEXT")

    
    # Set up the server
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('localhost', 8080))
    server.listen()
    print("Server started, waiting for connections...")
    
    # 外层循环:持续接受新的客户端连接
    while True:
        client, addr = server.accept()
        print(f'Connected by {addr}')
        
        try:
            # 内层循环:处理当前客户端的请求(支持单客户端多次请求)
            while True:
                # Receive login/sign-up data from the client
                data = client.recv(1024)
                if not data:  # 客户端断开连接时,recv返回空
                    break
                
                action, username, password = data.decode().split(':')
            
                if action == 'login':
                    recognizer = FaceRecognizer()
                    recognizer.load_faces("faces")
                    if recognizer.recognize_face(username):
                        cursor.execute('SELECT * FROM users WHERE username = ? AND password = ?', (username, password))
                        result = cursor.fetchone()
                    else:
                        print(f"{username} not matched!")
                        result = None
                    
                    if result:
                        msg_to_client = "welcome " + username
                        client.send(msg_to_client.encode())
                        sl = Salary()
                        sl.getSallary(username)                
                    else:
                        client.send('Invalid login'.encode())
        
                elif action == 'signup':
                    cm = SignUpCamera()
                    # Check if the password is strong enough
                    if not re.search(r'[A-Z]', password) or not re.search(r'[a-z]', password) or not re.search(r'[0-9]', password):
                        client.send('Password is not strong enough'.encode())
                    else:
                        # Check if the username is already in use
                        cursor.execute('SELECT * FROM users WHERE username = ?', (username,))
                        result = cursor.fetchone()

                        if result:
                            client.send('Username already in use'.encode())
                        else:
                            cursor.execute("INSERT INTO users (username, password, user_data) VALUES (?, ?, ? || '.jpg')", (username, password, username.lower()))
                            conn.commit()
                            cm.main(username)
                            client.send('Sign-up successful'.encode())
        except Exception as e:
            print(f"Error handling client {addr}: {e}")
        finally:
            # 处理完当前客户端请求后关闭连接
            client.close()
            print(f"Disconnected from {addr}")


if __name__ == "__main__":
    main()

修改说明

  • 将server.accept()放入外层while True循环,确保服务器能持续接受新的客户端连接。
  • 把client.close()移到finally块中,确保无论是否发生异常,客户端连接都会被正确关闭。
  • 添加了if not data:判断,当客户端主动断开连接时,内层循环退出,避免无效的recv调用。
  • 增加异常捕获,方便排查客户端处理过程中的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:47:51