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

Flask出现OSError: [WinError 10038]非套接字操作错误求助

Flask移除Flask Sockets后仍间歇性出现WinError 10038套接字错误

之前尝试过使用Flask Sockets,后续弃用并还原代码后,即使代码中已无任何双向套接字相关逻辑,仍会间歇性弹出套接字错误(每几分钟触发一次)。

以下是我的代码(代码质量一般,见谅):

import time, json, xxhash, threading, random
from flask import Flask, request
from string import digits
from random import choice
app = Flask(__name__)

target = 5
last_block, key = time.time(), int(''.join(choice(digits) for i in range(8)))
pending_transactions, pending_data = [], []

user_data = {}

def import_user_data(username):
    with open(f'user_data\\{username}.json', 'r') as f:
        return json.load(f)

def export_user_data(username, data):
    with open(f'user_data\\{username}.json', 'w') as f:
        return json.dump(data, f)

def create_user_data(user, password):
    try:
        with open(f'user_data\\{user}.json', 'x') as f:
            json.dump({"password": password, "balance": 0, "transactions": []}, f)
        return True
    except Exception:
        return False

def get_balance(user):
    data = import_user_data(user)
    return data.get("balance")

def post_transaction(amount, sender, recipient, memo):
    txid = xxhash.xxh64(random.randbytes(64)).hexdigest()

    if sender != "Mainnet":
        user = import_user_data(sender)
        if len(user["transactions"]) >= 25:
            user["transactions"].pop(-1)
        user["transactions"].append({"txid": txid, "sender": sender, "recipient": recipient, "amount": amount, "memo": memo})
        export_user_data(sender, user)

    user = import_user_data(recipient)
    if len(user["transactions"]) >= 25:
        user["transactions"].pop(-1)
    user["transactions"].append({"txid": txid, "sender": sender, "recipient": recipient, "amount": amount, "memo": memo})
    export_user_data(recipient, user)

    return txid
def payout(username):
    global target
    data = import_user_data(username)

    reward = target * 10 + 1

    data["balance"] += reward
    export_user_data(username, data)
    post_transaction(reward, "Mainnet", username, f"mining reward! (target: {target})")

def transfer(sender, recipient, amount):
    data = import_user_data(sender)

    if not float(data.get("balance")) < float(amount):
        data["balance"] -= float(amount)
        export_user_data(data, sender)

        data = import_user_data(recipient)
        data["balance"] += float(amount)

        export_user_data(data, recipient)

    return {"txid": post_transaction(amount, sender, recipient, memo)}

def new_block(block, last_block):
    global target, key

    t = block - last_block
    key = int(''.join(choice(digits) for i in range(8)))

    if t > 80:
        target -= 1
    if t < 50:
        target += 1

    for i in range(0, len(pending_transactions)):
        pass

def chain():
    global target, last_block

    try:
        while True:

            if time.time() - last_block > 81:
                target -= 1
                last_block = time.time()
                time.sleep(30)

    except Exception as e:
        print(e)

@app.route("/create_account")
def create_acc():
    try:
        e, t = time.time(), target

        if request.json["hash"] == xxhash.xxh64(request.json["nonce"], seed=int(e)).hexdigest():

            username, password = xxhash.xxh64(random.randbytes(64)).hexdigest(), xxhash.xxh64(random.randbytes(64)).hexdigest()
            create_user_data(username, password)

            return {"output": True, "username": username, "password": password}

    except Exception as e:
        return {"output": False, "info": e}

@app.route("/mine", methods=['GET', 'POST'])
def mine():
    global key, last_block, target

    if request.method == "GET":
        return {"target": target, "key": key}
    else:
        e, t = time.time(), target

        if request.json["hash"] == xxhash.xxh64(request.json["nonce"], seed=key).hexdigest():
            new_block(e, last_block)

            last_block = e

            payout(request.json["username"])

            return {"output": True, "info": "you have submitted a valid block!"}
        else:
            return {"output": False, "info": "your submission is invalid"}

if __name__ == '__main__':
    c = threading.Thread(target=chain)
    c.start()

    app.run(debug=True, port=80, host="127.0.0.1")

已尝试的无效解决操作:

  • 重装Flask及其依赖库
  • 参考相关技术帖子步骤排查
  • 重启电脑

错误回溯信息:

Exception in thread Thread-3:
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\threading.py", line 980, in _bootstrap_inner
    self.run()
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\threading.py", line 917, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\jerrb\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\werkzeug\serving.py", line 804, in serve_forever
    super().serve_forever(poll_interval=poll_interval)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\socketserver.py", line 232, in serve_forever
    ready = selector.select(poll_interval)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\selectors.py", line 324, in select
    r, w, _ = self._select(self._readers, self._writers, [], timeout)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\selectors.py", line 315, in _select
    r, w, x = select.select(r, w, w, timeout)
OSError: [WinError 10038] An operation was attempted on something that is not a socket

解决方案

这个错误是Flask调试模式的线程安全缺陷导致的,手动启动的额外线程和调试模式的代码重载机制冲突,引发套接字资源泄漏。

1. 关闭调试模式

直接修改app.run参数,关闭调试模式:

app.run(debug=False, port=80, host="127.0.0.1")

调试模式会自动重载代码,重启时旧套接字资源无法正确释放,是触发错误的核心原因。

2. 安全管理线程生命周期(保留调试模式时用)

如果必须保留调试模式,改用守护线程+事件控制的方式管理线程,避免重载时线程残留:

# 替换原线程启动代码
stop_event = threading.Event()

def chain():
    global target, last_block
    try:
        while not stop_event.is_set():
            if time.time() - last_block > 81:
                target -= 1
                last_block = time.time()
                stop_event.wait(30)  # 用wait替代sleep,方便快速终止
    except Exception as e:
        print(e)

@app.before_first_request
def start_chain_thread():
    c = threading.Thread(target=chain)
    c.daemon = True  # 设为守护线程,主进程退出时自动终止
    c.start()

if __name__ == '__main__':
    try:
        app.run(debug=True, port=80, host="127.0.0.1")
    finally:
        stop_event.set()

3. 更换端口测试

Windows下80端口可能被IIS、Skype等服务占用,换用非特权端口(如5000):

app.run(debug=False, port=5000, host="127.0.0.1")

4. 替换Python版本

你当前使用的是Microsoft Store版本的Python,该版本在权限和资源管理上存在兼容性问题,建议更换为Python官网下载的标准版本。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 08:27:15