0

udpソケット接続を介してクライアントからサーバーにファイルを送信する小さなプログラムを作成します。プログラムは正しく機能しますが、転送するファイルが8192 kbより大きい場合、ストリームが停止し、受信するファイルが破損します。これを回避するにはどうすればよいですか。制限?

server.py

host = ...
port = ...
filename = ...

buf = 2048
addr = (host, port)

UDPSock = socket(AF_INET, SOCK_DGRAM)
UDPSock.bind(addr)

f = open(filename, 'wb')

block,addr = UDPSock.recvfrom(buf)
while block:
    if(block == "!END"): # I put "!END" to interrupt the listener
        break
    f.write(block)
    block,addr = UDPSock.recvfrom(buf)

f.close()
UDPSock.close()

client.py

host = ...
port = ...
filename = ...

buf = 2048
addr = (host, port)

UDPSock = socket(AF_INET, SOCK_DGRAM)

f = open(filename, 'rb')

block = f.read(buf)
while block:
        UDPSock.sendto(block, addr)
        block = f.read(buf)

UDPSock.sendto("!END", addr)
f.close()
UDPSock.close()
4

6 に答える 6

2

tを送信する前に、ファイルを小さなチャンクに分割する必要があります。8192はかなり大きいので、これをインターネット経由で送信すると問題が発生する可能性があると思います。代わりに512バイトを使用します。また、UDPは信頼できるプロトコルではないことにも注意してください。つまり、一部のパケットがまったく届かない可能性があります。ファイルの転送にTCPを使用することをお勧めします。これにより、UDPを使用するときに自分で解決する必要のあるすべての問題が解決されます。

于 2010-09-26T11:39:03.353 に答える
1

大きなファイル転送にはtcpを使用することをお勧めします。

udpで行う必要があるのは、ファイルをチャンクに分割し、失われたチャンクを処理し、再試行して、パケットの順序を狂わせることです。

tcpを使用すると、いけません。

于 2010-09-26T11:46:53.433 に答える
1

ヒットした8192の制限は、Windowsのソケット送信および受信バッファーのサイズに対応します。1460バイトを超えるファイルでは、パケットがネットワークに接続される前にそれ以下に切り捨てられていたため、まったく機能しないことに驚いています。同じホスト内でテストしましたか?

それを理解したら、順不同で到着したパケットを2回以上処理するか、まったく処理しないようにする必要があります。UDPを使用する必要がありますか?初心者向けではありません。

于 2010-09-26T12:36:12.983 に答える
1

あなたがしているのは、TCPの再実装が非常に不十分なことだけです。UDPを使用する唯一の理由は、1対多の転送または常に実行されているエンタープライズサービスバスミドルウェアのためです。

信頼性の低い単方向トランスポートとしてUDPを使用することは、既存の明確に定義されたトランスポートを使い果たした後の非常に小さなニッチなソリューションと見なす必要があります。

インターネットを介した大規模なデータ転送の場合、小文字の「I」は依然として信頼できるだけであり、通常はアプリケーションのフレーミングとペイロードの検証を追加する必要があります。

FSP(UDP)、HTTP(TCP)、SPDY (最適化されたHTTP)などの既存のファイル転送テクノロジーを調査するか、 JBoss0MQなどの既存のメッセージ指向ミドルウェアシステムの上に独自の通信を展開する他の通信と統合することをお勧めします。

于 2010-09-27T07:06:52.200 に答える
1

UDPを使用する必要がある理由については、まだ説明していません。UDPには(単純な)輻輳管理がないため、大量のデータ転送用に設計されていません。

VoIPを送信している場合、「できるだけ速く」ではなく、単にリアルタイムで送信しない場合はどうでしょうか。

FWIW、一般的なVoIPシステムは、データを20ミリ秒程度のチャンクにパケット化します。したがって、13 kbpsを必要とするGSMのような音声コーデックを使用している場合は、パケットごとに260ビット(〜32バイト)にチャンクし、0.02秒ごとに送信するだけで済みます。

于 2010-09-27T07:26:39.923 に答える
1

UDPを使用する必要がある場合は、http://en.wikipedia.org/wiki/Trivial_File_Transfer_Protocolを参照してください。

信頼できるプロトコルを定義します。コンテキストでTCPが許可されている場合は、それを使用することをお勧めします。

于 2010-09-27T07:38:10.327 に答える