• 締切済み

C# UDPで大きなサイズのファイルを送信するには

C# UDPで大きなサイズのファイルを送信するには いつもお世話になっております。 UdpClientでの通信に挑戦しているのですが、ファイルを送信する段階になって詰まっています。 2MBほどあるファイルを送受信したいのですが、一度には送れないので分割して送信しようとしています。 ところが、分割すると上手くいきません・・・ 現在32767byteずつ送信しているのですが、32800byteなどのテキストファイルは2つに分割されて上手く送信できたのですが 実際に2MBほどあるファイルを送信してみると、送信はしてても受信ができていません。 受信できたのは2つほどで、分割されたデータのほとんどがどこかへ行ってしまったみたいです。 そこで質問です。 (1)考えられる原因、対処法はありますか? (2)UDPで大きいサイズのファイルを送受信する場合、通常どうしていますか? わかる方がいましたらお願いします。

みんなの回答

  • Yorisin
  • ベストアンサー率54% (364/663)
回答No.3

先にも出ていますが、送信手順を考えた方が良いですね。 TCP/IP, UDP/IPはデータが[確実に届くこと]はそもそも担保されていないので 上位層でカバーする必要があります。 通常のデータ通信では ・分割したデータにシーケンス番号(データの順序)を振り当てる ・シーケンス番号ごとにACKを返し、届いたことを送信側に伝える ・受信側は届いたデータをシーケンス番号の順に再度置き換える  (歯抜けでデータが来たときに、送信側から再送要求する場合もある) ・送信側に一定期間ACKが返ってこない場合、再送要求があった場合は  該当のデータを再度送信する ・一定期間で処理が完了しない場合はタイムアウトとして終了する といったシーケンスで通信を行います。 (初期段階のハンドシェイクは省略) ともかく、データが伝送路で破棄されることを前提に考え、 送信側では再送の仕組みを、受信側ではデータの再構築の仕組みを考えるべきでしょう。 なお、FTP通信はデータ部分はUDPを組み合わせているので、 参考にすると良いでしょう。 とりあえず ・送信側には受信データに対するACK処理  順序が入れ替わった場合の再組立処理 ・受信側にはACKなしの場合の再送処理 を追加してみてはどうでしょうか? あと、可能性は低いですが、データが化けていたり送信できていないとか? パケットをキャプチャしてネットワーク上に送信されているか、 また受信されているか(途中で破棄されていないか)、 期待するデータであるかなども確認して置いた方が良いかもしれません。

すると、全ての回答が全文表示されます。
  • YUI_AI
  • ベストアンサー率45% (303/661)
回答No.2

UDPの場合は、エラー時の再送、パケットの不達にも対応していないので、その処理を行う様にしないといけません。 ※簡単に言うと送信プロトコルを作ることになります。 例 1.送信元よりデータを送信(1パケット目)※受信側からの応答待ちに入る 2.受信元がデータを受けた時点で応答パケットを返信 ※ACK、NAKなのの応答コード   ※一定期間受信しない場合はパケットロスと判断してNAKを送信等の対応が必要 3.送信元が応答コードを判断して現パケットを再送するか次パケットを送信するか判断を行い、対応パケットを送信する。※応答待ちに入る 2.~3.を全データ送信完了まで繰り返す 単純に書いてますが、各パケットにパリティコードを追加する等、データの整合性を保つ必要もあると思います。 これが面倒であればTCPでの送信に切り替えた方が良いかと思います。

すると、全ての回答が全文表示されます。
回答No.1

「送った順に届くとは限らない」ので「順番に届くと思って受信」すると「分割されたデータのほとんどがどこかへ行ってしま」う事があります。 例えば「1番が来たから次は2番の筈。2番以外が来たら無視」とかって処理をすると「分割されたデータのほとんどを自分で捨ててしまう」ことになります。 パケットの到達順は「不定」なので「1番、3番、4番、2番、5番…」と言う順で届く可能性もあります。 この時に「1番が来たから次は2番の筈。2番以外が来たら無視」すれば、3、4番は消えて無くなります。 その後に来た2番だけは続いて受信されますが、3番は「既に捨てている」ので、もう2度と届きません。 3番が届く事は「永久にない」ですから、3番以降のブロックは「全部、捨てられ」ます。 結果として「受信できたのは2つほどで、分割されたデータのほとんどがどこかへ行ってしま」う事になります。

すると、全ての回答が全文表示されます。