2017-08-13 7 views
0

私は断続的にPythonを使用しています。私はAPIを介してブローカーアプリケーションから市場データと注文データを受け取るためにソケットモジュールを使用しています。私はまだヘッダー情報に基づいて、複数のデータの長さとヘッダーを受信するコードをする方法を混乱させる、私はデータを扱います。複数のデータ長をソケットストリーミングサーバーから受信しました - PYTHON3

複数のデータ長を受け取る方法と正しいstruct format関数でアンパックする方法を教えてください。

while True: 
    try: 
     """ 
     continously receive data from Server API (stock Market data streaming) 
     """ 
     brecvd = self.sock.recv(1024) 
     self.brecvdsize = len(brecvd) 
     # Unpack the header for correct struct formate to unpack 
     unpkr = self.struct.Struct('<lh') 
     recvd =self.struct.Struct.unpack_from(unpkr, brecvd) 

     Marketdepth = recvd[0] == 284 and recvd[1] == 26 
     Indices = recvd[0] == 228 and recvd[1] == 27 
     Feed = recvd[0] == 384 and recvd[1] == 22 
     BidOffer = recvd[0] == 145 and recvd[1] == 28 
     Msg = recvd[0] == 360 and recvd[1] == 99 
     #Msg to be checked for 260 or 360 

     if Marketdepth: 
      self.Marketdepthresponse(brecvd) 
      Marketdepth = False 

     elif Indices: 
      self.Indicesresponse(brecvd) 
      Indices = False 

     elif Feed: 
      self.feedresponse(brecvd) 
      Feed = False 

     elif BidOffer: 
      self.Bidoffer(brecvd) 
      BidOffer = False 

     elif Msg: 
      self.GeneralMsg(brecvd) 
      Msg = False 

     else: 
      Marketdepth = False 
      Indices = False 
      Feed = False 
      BidOffer = False 
      Msg = False 
      pass 


    except Exception as e: 
     self.errorcount += 1 
     print('***Run Loop Receive Issue: {0}'.format(str(e))) 
+0

私はあなたのextreamの知識から次のことを知りたいと思います。注:メソッド 'StartTTAPI'が呼び出され、スレッドで実行されています。 複数のデータ長を受け取る方法と正しいstruct format関数で解凍する方法を教えてください。 多くの場合、例外 'struct.error'が取得されます。アンパックには、長さxxxのバイトオブジェクト(すべてのアンパックメソッド用)が必要です 数分後にサーバーからデータが受信されませんが、サーバーはデータをストリーミングしています サーバーがデータをストリーミングしている間にすべてのデータを受信して​​おらず、例外またはエラーをスローしません。 –

答えて

1

あなたがデータの1024のバイトに0(ソケットが閉じられた)からどこでも受け取ることができself.sock.recv(1024)呼び出します。完全なメッセージを解凍するのに十分なデータを受け取ることができない場合があります。完全なメッセージが解凍され、次のメッセージの一部が受信されるまで、データの受信とバッファリングを続行する必要があります。 TCPは、メッセージ境界インジケータのないストリーミングプロトコルです。 TCPを使用するプロトコルは、完全なメッセージの外観を定義する必要があります。

プロトコルの詳細がなければ、プロトコルを作成して例を挙げることしかできません。これは完全にテストされていませんが、あなたにアイディアを与えるべきです。

プロトコル:4バイト長(ビッグエンディアン)とそれに続くデータバイト。

def get_message(self): 
    # read the 4-byte length 
    data = self.get_bytes(4) 
    if not data: 
     return None # indicates socket closed 
    if len(data) < 4: 
     raise IncompleteMessageError 

    # process the length and fetch the data 
    length = struct.unpack('>L',data)  
    data = self.get_bytes(length) 
    if len(data) < length: 
     raise IncompleteMessageError 
    return data 

def get_bytes(self,count): 
    # buffer data until the requested size is present 
    while len(self.buffer) < count: 
     new_data = self.sock.recv(1024) 
     if not new_data: # socket closed 
      remaining,self.buffer = self.buffer,b'' 
      return remaining # return whatever is left. 
     self.buffer += new_data 

    # split off the requested data from the front of the buffer 
    data,self.buffer = self.buffer[:count],self.buffer[count:] 
    return data 
+0

私はあなたのextream知識から次のことを知りたいと思います。注:メソッド 'StartTTAPI'が呼び出され、スレッドで実行されています。 複数のデータ長を受け取る方法と正しいstruct format関数で解凍する方法を教えてください。 多くの場合、例外 'struct.error'が取得されます。アンパックには、長さxxxのバイトオブジェクト(すべてのアンパックメソッド用)が必要です 数分後にサーバーからデータが受信されませんが、サーバーはデータをストリーミングしています サーバーがデータをストリーミングしている間にすべてのデータを受信して​​おらず、例外またはエラーをスローしません。 –

+0

@manjunathan新しい質問をしてください。既存の質問を編集したため、現在の回答はあまり意味がありません。私はあなたの編集をロールバックする自由を取った。代わりに、プロトコルの詳細など、現在の質問に詳細を追加すると、自分の答えを編集して問題を対象とすることができますが、質問を完全に変更することはできません。 –

+0

新しい質問にお答えします。私はすみません、私は新しいstackoverflowになります –

関連する問題