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
相关产品推荐
相关产品推荐

