0

クライアントサーバー通信があり、受信メッセージを処理するために次のサーバーを作成しましたが、メッセージがバッファーよりも大きい場合は失われます。メッセージがバッファ サイズより大きい場合、パッケージ全体を受信するにはどうすればよいですか? 可能性はありますか、またはクライアントに強制的に(最大バッファサイズでメッセージを送信する)、バッファサイズ内でメッセージを送信させる必要がありますか?

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>" )
4

1 に答える 1

3

あらゆる種類のパケット化されたメッセージ形式を扱う場合、実際には次の 2 つの選択肢しかありません。

  1. バッファーがメッセージ全体を処理するのに十分な大きさであることを確認してください。
  2. 部分的なメッセージを解析できるようにコードを記述します。

ただし、「バッファ」と言うときは、パラメータのことを意味しているわけではありません。好きなだけ小さくして、メッセージ全体が得られるまでループを何度もrecv()回るだけです。while

したがって、バッファリングのアプローチを取るには、次のようにすることができます。

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]

これが機能するの</packet>は、見つからない場合partition()でも、最初の項目が文字列全体で、他の 2 つは空である 3 タプルを返すためです。そのため、区切り文字に空でない文字列が返される間ずっとpartition()、パケットが見つかりました。それが空になるとすぐに、部分的なパケットがあるmsg(または空になる) ため、パケット全体を再び取得するまで、ネットワークからの読み取りに戻ります。

これには、文字列内のメッセージ全体をバッファリングする必要がありmsgますが、これらのメッセージが非常に大きくなる (数メガバイト) と予想される場合を除き、問題ありません。これは、メッセージに大きなファイルが含まれている場合などに発生する可能性があります。この場合、より賢く、データをディスクにスワップアウトしたり、受信したデータを処理したりする必要があります。

不明な点がありましたらお知らせください。

編集:追加する必要があります。通常、バッファー (つまりmsg) が大きくなりすぎないようにすることをお勧めします。大きすぎる場合は、何か問題が発生したため、接続を閉じる必要があります。これにより、誤ってまたは悪意を持ってシステムのメモリがなくなるまで、何かがアプリケーションにエンドレス データを供給するのを停止します。また、メッセージ内で文字列が実際に発生しないようにする必要があります</packet>。メッセージが誤って半分に分割されます。

于 2013-01-10T14:47:36.150 に答える