Python TCP缓冲区溢出
我有一个客户机-服务器通信,我编写了下面的服务器来处理传入的消息,但是如果消息大于缓冲区,它就会丢失。如果消息大于缓冲区大小,如何接收整个包?有没有可能,或者我必须强制客户机(以最大缓冲区大小在begging发送消息)在缓冲区大小内发送消息Python TCP缓冲区溢出,python,tcp,Python,Tcp,我有一个客户机-服务器通信,我编写了下面的服务器来处理传入的消息,但是如果消息大于缓冲区,它就会丢失。如果消息大于缓冲区大小,如何接收整个包?有没有可能,或者我必须强制客户机(以最大缓冲区大小在begging发送消息)在缓冲区大小内发送消息 msg ='' while( True ): msg += server.recv( 20480 ) aSplit = msg.p
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>" )
msg=''
虽然(正确):
msg+=server.recv(20480)
aSplit=msg.partition(“”)
#我们收到了完整的信息
而(aSplit[1]==“”):
messagehandler(aSplit[0]+“”)
msg=aSplit[2]
aSplit=msg.partition(“”)
在处理任何类型的打包消息格式时,您实际上只有两种选择:
recv()
的参数-您可以将其设置得尽可能小,只需在中循环多次,直到得到完整的消息
因此,要采用缓冲方法,您可以执行以下操作:
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]
msg=''
尽管如此:
msg+=server.recv(8192)
尽管如此:
aSplit=msg.partition(“”)
如果不是aSplit[1]:
打破
messagehandler(aSplit[0]+“”)
msg=aSplit[2]
这是因为如果未找到
,则分区()
仍会返回一个三元组,其中第一项是整个字符串,其余两项为空。因此,partition()
始终为分隔符返回一个非空字符串,然后找到一个数据包。一旦它是空的,msg
(或者它是空的)中就有一个部分数据包,所以我们继续从网络中读取,直到我们再次获得整个数据包
这确实涉及到在msg
字符串中缓冲整个消息,但这没关系,除非您期望这些消息变得非常大(多兆字节)-例如,如果消息包含大文件,则可能发生这种情况。在这种情况下,您需要更聪明一些,做一些类似于将数据交换到磁盘或在接收数据时处理数据的事情
如果我对此不清楚,请告诉我
编辑:我应该补充一点,通常最好确保缓冲区(即msg
)不会太大-如果缓冲区太大,则需要关闭连接,因为出现了问题。这会停止向应用程序提供无休止的数据,直到系统内存意外或恶意耗尽。此外,您需要非常确定字符串
实际上不会出现在消息内部-这会将消息错误地一分为二。处理任何类型的打包消息格式时,您实际上只有两种选择:
确保缓冲区足够大,可以处理整个消息
编写代码,以便它能够解析部分消息
不过,当我说“buffer”时,我不是指recv()
的参数-您可以将其设置得尽可能小,只需在中循环多次,直到得到完整的消息
因此,要采用缓冲方法,您可以执行以下操作:
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]
msg=''
尽管如此:
msg+=server.recv(8192)
尽管如此:
aSplit=msg.partition(“”)
如果不是aSplit[1]:
打破
messagehandler(aSplit[0]+“”)
msg=aSplit[2]
这是因为如果未找到
,则分区()
仍会返回一个三元组,其中第一项是整个字符串,其余两项为空。因此,partition()
始终为分隔符返回一个非空字符串,然后找到一个数据包。一旦它是空的,msg
(或者它是空的)中就有一个部分数据包,所以我们继续从网络中读取,直到我们再次获得整个数据包
这确实涉及到在msg
字符串中缓冲整个消息,但这没关系,除非您期望这些消息变得非常大(多兆字节)-例如,如果消息包含大文件,则可能发生这种情况。在这种情况下,您需要更聪明一些,做一些类似于将数据交换到磁盘或在接收数据时处理数据的事情
如果我对此不清楚,请告诉我
编辑:我应该补充一点,通常最好确保缓冲区(即msg
)不会太大-如果缓冲区太大,则需要关闭连接,因为出现了问题。这会停止向应用程序提供无休止的数据,直到系统内存意外或恶意耗尽。另外,您需要非常确定字符串
实际上不能出现在消息内部-这将错误地将消息一分为二。当我发送100kB的消息时,我仍然会丢失消息的结尾,这听起来好像您超出了操作系统的缓冲区来存储数据。例如,如果您使用的是TCP连接,那么您可以发送的数据量是有限的—无论您的客户端在做什么,这都适用,它可能一次读取GB,而且这种情况仍然会发生。在发送端,您需要注意send()
中的返回代码,它将告诉您发送了多少数据。您的应用程序必须在循环中不断发送其余部分,直到全部发送完毕。我建议你读一读。特别是,读一读这一节-我引用:现在我们来谈谈套接字的主要障碍-发送和接收在网络缓冲区上运行。它们不一定能处理您交给它们(或期望从它们那里得到)的所有字节,因为它们的主要焦点是han