我现在用Python开发一个聊天服务器。 我正在将pyOpenSSL应用于我用于测试的聊天服务器和虚拟客户端。 但是每当从虚拟客户端向服务器发送文本消息和照片文件时,pyOpenSSL都会返回重大错误,这会导致我停止使用pyOpenSSL,如下所示。
send_text_message() : exception : [Errno 1] _ssl.c:1309: error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry
send_text_message() : exception : [Errno 1] _ssl.c:1309: error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry
send_text_message() : exception : [Errno 1] _ssl.c:1309: error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry
send_text_message() : exception : [Errno 1] _ssl.c:1309: error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry
send_text_message() : exception : [Errno 1] _ssl.c:1309: error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry
send_text_message() : exception : [Errno 1] _ssl.c:1309: error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry
send_text_message() : exception : [Errno 1] _ssl.c:1309: error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry
你能让我知道如何解决这个错误吗? 还有一个错误导致虚拟客户端死亡。
[client1|chatting1A] socket closed : device_id : client1, client_chatting_id : chatting1A, error : [Errno 10053]
Exception in thread Thread-8:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 810, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 1082, in run
self.function(*self.args, **self.kwargs)
File "D:\temp\uTok1\uTokSocketServer\com\rurusoft\utok\DummyClient.py", line 97, in send_photo_message
sock.write(message)
File "C:\Python27\lib\ssl.py", line 172, in write
return self._sslobj.write(data)
error: [Errno 10054]
没有pyOpenSSL,虚拟客户端和服务器运行良好。应用pyOpenSSL会导致意外问题:(。 如果您遇到问题或解决问题,请告诉我。 ....如果没有解决错误的方法,我宁愿找出不使用OpenSSL的其他选择。 或者您是否知道任何可以加密/解密聊天消息和在机器之间传输的个人文件的替代品?
虽然在写入(发送)数据之前我已经存储了要在本地变量中发送的数据,但每次都会发生错误。
json_encoded = json.dumps(data)
while True:
try:
sock.write(json_encoded)
break
except Exception, e:
Log.print_log(self.LOG_TAG, 'send_text_message() : exception : %s' % (e))
time.sleep(0.05)
解决: 正如@David Schwartz评论的那样,以下代码解决了上层问题。
import StringIO
...
io = StringIO.StringIO()
io.write(json.dumps(data))
buffer = io.getvalue()
while True:
try:
sock.write(buffer)
break
...
答案 0 :(得分:2)
OpenSSL对如何重试写入有非常严格的要求 - 特别是不得更改缓冲区的地址和内容。当您重试写入时,必须使用 exact 相同的缓冲区重试(相同的内容是不够的,当然,绝对禁止使用不同的内容)。
例如,这已经破了:
ssl_socket.send(send_buffer.getvalue())
由于您没有存储传递给send
的值,如果您需要重试send
,您如何传递相同的值?无法保证随后对getvalue
的调用将返回相同的结果。如果缓冲区移动,重复此操作可能会产生错误的写入重试,它可以随时进行。
更新:您的代码不会阻止缓冲区更改。没有反映缓冲区的对象没有变化。尝试:
io = StringIO()
json.dumps(data, io)
buffer = io.getvalue()
while True:
try:
sock.write(buffer)
break
此处,io
是缓冲区,getvalue
仅在其上调用一次。