Python TCP缓冲区溢出

时间:2013-01-10 14:08:42

标签: python tcp

我有一个客户端服务器通信,我编写了以下服务器来处理传入的消息,但是如果消息大于缓冲区则会丢失。如果消息大于缓冲区大小,我怎样才能收到整个包?有没有可能,或者我必须强制客户端(在最大缓冲区大小的乞讨时发送消息)在缓冲区大小内发送消息?

msg ='' 
while( True ):                 
     msg += server.recv( 20480 )                                    
     aSplit = msg.partition( "</packet>" ) 
     #We received the full message
     while( aSplit[ 1 ] == "</packet>" ):                           
          messagehandler(  aSplit[ 0 ] + "</packet>" )                        
          msg = aSplit[ 2 ]
          aSplit = msg.partition( "</packet>" )

1 个答案:

答案 0 :(得分:3)

在处理任何类型的分组化消息格式时,您实际上只有两种选择:

  1. 确保您的缓冲区足以处理整个邮件。
  2. 编写代码,以便它可以解析部分消息。
  3. 当我说“缓冲区”时,我并不是指recv()的参数 - 您可以根据需要调整它,只需绕过while循环多次,直到你有一个完整的信息。

    所以,采取缓冲方法你可以做这样的事情:

    msg = ''
    while True:
        msg += server.recv(8192)
        while True:
            aSplit = msg.partition("</packet>")
            if not aSplit[1]:
                break
            messagehandler(aSplit[0] + "</packet>")
            msg = aSplit[2]
    

    这是有效的,因为如果找不到</packet>,那么partition()仍会返回一个3元组,其中第一个项目是整个字符串,其他两个是空的。因此,partition()一直为分隔符返回一个非空字符串,然后找到一个数据包。只要它是空的,msg中有一个部分数据包(或者它是空的),所以我们回到网络读取,直到我们再次获得整个数据包。

    这确实涉及在msg字符串中缓冲整个消息,但除非您希望这些消息变得非常大(多兆字节),否则这很好 - 例如,如果消息包含大文件,则可能会发生这种情况。在这种情况下,您需要更聪明,并执行诸如将数据交换到磁盘或在收到数据时处理数据。

    如果我不清楚这一点,请告诉我。

    编辑:我应该补充一点,通常一个好主意是确保缓冲区(即msg)不会变得太大 - 如果确实如此,那么你需要关闭连接,因为出了问题。这会阻止向应用程序提供无限数据的内容,直到内存在系统上耗尽,无论是意外还是恶意。此外,您需要非常确定字符串</packet>实际上不会在消息中发生 - 这会将消息错误地分成两半。