如何在Python / Jython中只读取套接字中的最新数据和/或清空套接字

时间:2013-10-23 01:56:49

标签: linux sockets python-2.7 jython-2.5

我有一堆数据通过套接字连接进入,而对于我的应用程序,我只关心最新的数据。消息是json格式的文本字符串,由换行符分隔。我想弄清楚的只是阅读最新消息的干净而有效的方式。消息大约每30ms左右进入。我的一个问题是在我的代码加载之前消息开始出现,因此可能会有很多无用的消息,我不希望它通过。

有什么建议吗?

我正在使用jython,它与python非常相似,除了一些不方便的东西,但是套接字没问题。

到目前为止我尝试过的代码片段:

# ...
# This code is repeatedly called every 30 ms or so
in_file = sock_in.makefile( 'r' )
data_in = None
try:
  data_in = json.loads( in_file.readline() )
except JSONDecodeError:
  try:
    data_in = json.loads( in_file.readline() )
  except JSONDecodeError:
    print( "ERROR: malformed message, dropping data" )
    return
# do stuff with data_in
# ...

这基本上是从套接字中读取的,如果它碰巧抓住了一条缺少某些消息的块,它会再次尝试并抓取下一个(到目前为止每次都有效)。 我的问题是,如果消息进入太快(它们是),它似乎首先读取旧的消息,而只有最新消息才有用。 这种方法似乎没问题,但我觉得它可以好多了。

我试过的另一件事是:

   # ...
   self.buf = ""
   # ... This code is repeatedly called every 30ms or so
   self.read_socket( self.sock_in )
   data_in = json.loads( self.odom_str )
   # ...
   def read_socket( self, sock ):
     out = self.buf
     while True:
         try:
             data = sock.recv( 64 )
         except:
           return False
         if not data:
             break
         nl = data.find('\n')
         if nl >= 0:
             nl += 1
             out += data[:nl]
             self.buf = data[nl:]
             del data
             break
         out += data
     self.odom_str = out
     return True

第二种方法看起来更好,但表现更差。

成功读取后是否有某种方法可以清空套接字文件?或者从它的结尾阅读一个简单的方法?或者这实际上是从最后读取而我感到困惑? 我是新手使用套接字,而且我一直在尝试的很多东西可能都是可怕的风格,所以任何帮助都会非常感激:)

谢谢!

1 个答案:

答案 0 :(得分:0)

到目前为止,我提出的最好的方法是将端口设置为非阻塞,然后连续读取,直到没有更多数据,然后使用读取的最后一部分数据。代码看起来像这样:

  self.sock_in.setblocking(0)

# ...

  while True:
    if self.read_socket( self.sock_in ):
      try:
        data_in = json.loads( self.odom_str )
      except JSONDecodeError:
        break
      self.sensor_data = data_in
    else:
      break