2017-01-11 8 views
3

サーバーからクライアントへのデータの受信に問題があります。私は、サーバーからデータを受信しようとする次のクライアント側の関数があります。 socket.sendall (data)関数を使用してサーバーから送信されたデータはbuff_sizeより大きいので、すべてのデータを読み取るにはループが必要です。ソケット。 socket.recv()ですべてのデータを受け取る方法?

def receiveAll (sock): 
    data = "" 
    buff_size = 4096 
    while True: 
     part = sock.recv (buff_size) 
     data + = part 
     if part <buff_size: 
      break; 
    return data 

私に発生した問題は、最初の反復(最初の4096メガバイトを読む)した後、第二に、プログラムがpart = sock.recv (buff_size)内の他のデータを待ってブロックされていることです。 recv()は、他の欠けているデータを読み続けることができますか?ありがとうございました。

+0

コードが二次的な動作をする可能性がありますが、これは本当に悪いことです。代わりにリストと '' '.join() 'を使用してください。 –

答えて

2

あなたの解釈は間違っています。あなたのコードはサーバから取得したすべてのデータを読み込みます。着信データの受信を停止する必要があることはわかりません。それは、サーバーが持っていたすべてのものを送信したことを知らない。すべての

まず、これらの線

if part <buff_size: 
     break; 

は非常に間違っていることに注意してください。まず、文字列をint(Python3.xでは例外をスローする)と比較しています。しかし、あなたが if len(part) <buff_size:を意味していたとしても、これはまだ間違っています。まず第一に、ストリーミングの途中で遅れがあるかもしれないし、小さいものを読むのは buff_sizeだけです。あなたのコードはそこで停止します。

また、サーバがbuff_sizeの倍数のサイズのコンテンツを送信する場合、ifの部分は決して満たされず、.recv()に永久にハングします。

サイドノート:セミコロンは使用しないでください。;それはPythonです。


は、それらのは、サーバ側のmodyfingせずに正しく使用することができ、あなたの問題ではなくなしに、いくつかの解決策があります。

クライアントとして、いつ読書を停止するかを知る必要があります。しかし、それを知る唯一の方法は、サーバーが何か特別なことをして、それを理解する場合です。これは通信プロトコルと呼ばれます。あなたは、送受信するデータに意味を加えなければなりません。例えば

あなたはHTTPを使用している場合、サーバーは今クライアントとしてあなたはあなただけ12345バイトを読み取る必要があることを知っている(あなたのバッファが同じ大きさする必要がありますが、それとしない身体の前に、このヘッダContent-Length: 12345を送信あなたが何度もループを辿ってすべてを読む必要があることを知っています)。

一部のバイナリプロトコルは、たとえば最初の2または4バイトでコンテンツのサイズを送信する場合があります。これはクライアント側でも簡単に解釈できます。

簡単な解決方法は次のとおりです。すべてのデータを送信した後にサーバーを接続を閉じるだけです。次に、コードにチェックif not part: breakを追加するだけです。

+0

ありがとう、私はそれを試して、それは働いた –

関連する問題