0

ソケット接続を介して大量のデータを受信して​​いますが、アプリケーションでは最新のデータのみを気にしています。メッセージは、改行で区切られた json 形式のテキスト文字列です。私が理解しようとしているのは、最新のメッセージを読むだけのクリーンで効率的な方法です。メッセージは約 30 ミリ秒ごとに送信されます。私の問題の 1 つは、コードがロードされる前にメッセージが届き始めることです。そのため、通過させたくない無駄なものがたくさんある可能性があります。

助言がありますか?

私は 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

この 2 番目のアプローチは見た目は良くなりましたが、パフォーマンスは大幅に低下しました。

読み取りが成功した後にソケットファイルを空にする方法はありますか? または、最後から読みやすい方法はありますか?それとも、これは実際に最後から読んでいて、混乱していますか?私はソケットを使用するのが初めてで、私が試してきたことの多くはおそらくひどいスタイルなので、どんな助けも大歓迎です:)

ありがとう!

4

1 に答える 1

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
于 2013-10-28T18:14:59.463 に答える