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

如何修正Python HTTPS服务器代码中的运行报错问题?

HTTPS服务器报错原因及解决方案

问题描述

生成HTTPS密钥的命令

openssl req -x509 -newkey rsa:2048 -keyout privkey.pem -out cert.pem -days 365

报错的Python服务器代码(simple-https-server.py)

from http.server import HTTPServer, BaseHTTPRequestHandler
import ssl

httpd = HTTPServer(('localhost', 4446), BaseHTTPRequestHandler)

httpd.socket = ssl.wrap_socket (httpd.socket, 
        keyfile="privkey.pem", 
        certfile='cert.pem', server_side=True)

httpd.serve_forever()

执行报错信息

Traceback (most recent call last):
  File "/usr/lib/python3.9/ssl.py", line 1020, in _create
    self.getpeername()
OSError: [Errno 128] Transport endpoint is not connected

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/cemfa/programs/html/gaming/backup/html/simple-https-server.py", line 7, in <module>
    httpd.socket = ssl.wrap_socket (httpd.socket,
  File "/usr/lib/python3.9/ssl.py", line 1439, in wrap_socket
    return context.wrap_socket(
  File "/usr/lib/python3.9/ssl.py", line 501, in wrap_socket
    return self.sslsocket_class._create(
  File "/usr/lib/python3.9/ssl.py", line 1032, in _create
    notconn_pre_handshake_data = self.recv(1)
  File "/usr/lib/python3.9/ssl.py", line 1262, in recv
    return super().recv(buflen, flags)
BlockingIOError: [Errno 11] Resource temporarily unavailable

用户疑问:

  1. 该报错产生的原因是什么?
  2. 为何代码在Windows Python环境下可正常运行,但在Cygwin(Linux模拟器)中运行失败?

原因分析

核心报错原因

你错误地对监听套接字直接调用了ssl.wrap_socket()。HTTPServer初始化后的socket是用于监听客户端连接的套接字,而非已建立的客户端连接套接字。ssl.wrap_socket()需要在已完成三次握手的客户端连接上执行SSL握手,直接包装监听套接字时,SSL层会尝试读取数据触发握手,但此时没有任何客户端连接,就会抛出"Transport endpoint is not connected"错误,后续进一步触发阻塞IO异常。

Cygwin与Windows的差异原因

  • Windows平台的Python网络实现对这种错误用法做了兼容处理,允许直接包装监听套接字并正常工作;
  • Cygwin遵循Linux的网络套接字规范,严格要求SSL包装操作必须在已建立的客户端连接套接字上执行,因此会触发错误。你提到的"低级网络操作权限"不是本次问题的核心原因(你使用的4446端口大于1024,无需管理员权限)。

修正后的代码

方案1:在请求处理器中包装连接套接字

重写BaseHTTPRequestHandler的setup方法,在每次接受客户端连接后再进行SSL包装:

from http.server import HTTPServer, BaseHTTPRequestHandler
import ssl

class SSLRequestHandler(BaseHTTPRequestHandler):
    def setup(self):
        # 对已建立的客户端连接进行SSL包装
        self.connection = ssl.wrap_socket(
            self.connection,
            keyfile="privkey.pem",
            certfile='cert.pem',
            server_side=True
        )
        super().setup()

httpd = HTTPServer(('localhost', 4446), SSLRequestHandler)
httpd.serve_forever()

方案2:使用SSLContext(推荐,Python 3.7+)

通过ssl.SSLContext创建并配置SSL上下文,再包装监听套接字,这种方式更符合现代Python SSL最佳实践:

from http.server import HTTPServer, BaseHTTPRequestHandler
import ssl

# 创建TLS服务器上下文并加载证书密钥
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile='cert.pem', keyfile='privkey.pem')

httpd = HTTPServer(('localhost', 4446), BaseHTTPRequestHandler)
# 用上下文包装监听套接字
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)

httpd.serve_forever()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:55:15