Python:Windows Vista 上的 2.7.2 Egenix PyOpenSSL:0.13.0
我正在尝试编写代理服务。基本上,代理服务侦听常规套接字和 SSL 套接字,在两者之间中继数据。
我能够半可靠地中继数据,但是当 SSL 套接字另一端的服务器完成发送数据时,我收到一个虚假信号,表明有更多数据可供读取。代码基本上是这样的:
(rs, ws, xs) = select.select([client, sslserver], [], [])
for r in rs:
if r == client:
# tons of client code
elif r == sslserver:
(rs, ws, xs) = select.select([sslserver], [], [], 0)
print 'Reading server: %s, %s' % (len(rs), server.pending())
while len(rs) > 0 or sslserver.pending() > 0:
t = sslserver.read(sslserver.pending())
# Do more useful stuff
(rs, ws, xs) = select.select([sslserver], [], [], 0)
Reading server: 1, 0
使用此代码,我有时会在进入读取块之前看到文本。当我实际执行t = sslserver.read(sslserver.pending())
时,结果是一个折腾。我经常遇到 EOF 异常(SSL.SysCallError()[1] == 'Unexpected EOF')。问题是有时这是一个真正的 EOF,有时 SSL 只是没有提供任何数据。
但是,如果我将读取行更改为这样读取
t = sslserver.read(4096)
这是我在大多数套接字读取代码中的习惯,而不是得到任何指示 EOF(常规套接字会!select 表示套接字已准备好读取。没有要读取的数据。所以立即不返回数据!),当没有数据可供读取时,我的代码就会阻塞。当然,这没有任何意义。毕竟,套接字已准备好读取。它应该只是阻塞,直到 EOF 通过解密阶段。
但事实并非如此。这是一个永久的块。
我有哪些选择?我现在绝对相信 select.select 对于 PyOpenSSL 套接字是不安全的。是否有其他方法可以使用常规套接字监视 SSL 套接字,或者我是否需要将 SSL 套接字移动到单独的线程并使用普通套接字将数据中继到我的主线程?