Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python套接字recv需要很长时间才能传递数据包_Python_Linux_Sockets_Networking_Delay - Fatal编程技术网

Python套接字recv需要很长时间才能传递数据包

Python套接字recv需要很长时间才能传递数据包,python,linux,sockets,networking,delay,Python,Linux,Sockets,Networking,Delay,我有一个Python3程序,它向主机发送短命令并返回短响应(都是20字节)。它没有做任何复杂的事情 插座是这样打开的: self.conn = socket.create_connection( ( self.host, self.port ) ) self.conn.settimeout( POLL_TIME ) while( True ): buf = self.conn.recv( 256 ) # append buffer to bigger buffer,

我有一个Python3程序,它向主机发送短命令并返回短响应(都是20字节)。它没有做任何复杂的事情

插座是这样打开的:

  self.conn = socket.create_connection( ( self.host, self.port ) )
  self.conn.settimeout( POLL_TIME )
  while( True ):
    buf = self.conn.recv( 256 )
    # append buffer to bigger buffer, parse packet once we've got enough bytes
使用方法如下:

  self.conn = socket.create_connection( ( self.host, self.port ) )
  self.conn.settimeout( POLL_TIME )
  while( True ):
    buf = self.conn.recv( 256 )
    # append buffer to bigger buffer, parse packet once we've got enough bytes
在我的程序运行了一段时间(通常是几个小时)之后,有时它会进入一种奇怪的模式——如果我使用tcpdump,我可以看到一个响应包到达本地机器,但是recv直到30秒(Windows)到1米(Linux)之后才给我这个包。时间是随机的+/-大约10秒。我想知道包是否被延迟到下一个包到达,但这似乎不是真的

同时,同一程序还在另一个线程上使用相同的代码操作第二个套接字连接,该线程将继续正常工作

这种情况并非总是发生,但在一个月内发生了好几次。有时,在它之前会有几秒钟的数据包,需要越来越长的时间才能到达,但大多数情况下,它只是从OK(正常)到完全中断。在我重新启动服务器之前,它大部分时间都会坏几个小时,但昨晚我注意到它正在恢复并恢复正常运行,所以它不是不可恢复的

CPU使用率几乎为零,并且在同一台机器上没有其他任何东西在运行

最奇怪的是,这种情况发生在Windows的Linux子系统(两台不同的笔记本电脑)和Linux(运行AmazonLinux的AWS小实例)上

我看了一下使用GDB实现socket.recv()的CPython。查看源代码,它似乎将对socket.recv()的调用直接传递到底层recv()。但是,虽然外部函数sock_recv()(实现socket.recv())经常被调用,但它只在实际有数据要从套接字读取时才调用recv(),使用socket_call()函数调用poll()/select(),查看是否有数据等待。对recv()的调用直接发生在应用程序收到数据包之前,因此延迟在该点之前,而不是recv()和我的代码之间

关于如何解决这个问题有什么想法吗

(Linux和Windows机器都更新为最新的everything,Python是Python 3.6.2)

[编辑]这个问题变得更加奇怪。我受够了,写了一个方法来检测这个问题(在一行中查找十个延迟到达的数据包,其往返时间几乎相同),断开连接并重新连接(通过关闭以前的连接并创建一个新的套接字对象)。。。但它不起作用。即使有一个新的套接字对象,延迟的数据包也会保持完全相同的延迟量。所以我改变了方法,完全杀死运行该代码的线程并重新启动它,原因是可能存在一些线程本地状态。那仍然不起作用。我唯一剩下的办法就是杀掉整个程序,让看门狗重新启动它


[edit2]杀掉整个程序并用外部看门狗重新启动它起作用。这是一个糟糕的解决方案,但至少是一个解决方案。

原因在于:Axalix:套接字已经设置了超时(100ms)。在几次socket.recv()调用均未返回任何结果后,数据包被延迟了整整一分钟才送达。您能否生成一个?@AndyWalker,但只有一个超时时间是不够的。我在第一条评论中发布的链接不是关于超时的。你能将以太网线从你的计算机上拔下30秒,然后重新插上吗?(我的怀疑是,您可能看到TCP通过将重发速率和窗口大小拨回极小值来响应临时网络中断)