pyOpenSSL SSL3_WRITE_PENDING:糟糕的写入重试,返回self._sslobj.write(data)错误:[Errno 10054]

2024-04-28 17:20:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我现在正在用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
    ...
    

Tags: textsendsslmessageexceptionerrorwritebad
1条回答
网友
1楼 · 发布于 2024-04-28 17:20:37

OpenSSL对如何重试写操作有非常严格的要求——特别是缓冲区的地址和内容不能更改。当您重试写操作时,必须使用相同的缓冲区重试(相同的内容是不够的,当然,绝对禁止不同的内容)。

例如,这是坏的:

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

相关问题 更多 >