2012-02-10 17 views
0

私はasynソケットを使っています。私はコールバック関数 'onDataReceived'を持っています。これは、データを受け取るたびに呼び出されます。C#ソケット、大きなファイルを受信

私は一度に1つの文字を取得していたので、socketPacketデータバッファを大きな配列に変更しました。データを受け取った時点で一度にすべて取得できますが、サイズの大きいファイルを送信しようとすると、配列サイズを超えても機能しません。

私の質問はこれです。私はマルチスレッドのソケットサーバーを持っています。すべてのデータが受信されると、どのように確定することができますか?例えば、イメージを送る必要があります。イメージをbase64にエンコードし、コマンド "BASE64IMAGE"を作成してから、サーバーはEND_OF_DATAに達するまで文字列を読み取ります。それを行う良い方法はありますか?ありがとう!

+0

HTTPプロトコルを使用してファイルを送信できます。そのため、httpヘッダーを使用して、送信されるデータの詳細を表すことができます。また、httpベースのソケットクラスをライブラリとして利用できます –

答えて

5

私の質問はこれです。私はマルチスレッドのソケットサーバーを持っています。すべてのデータが受信されると、どのように確定することができますか?

(イメージまたは何だかどうか - 大きいかもしれないデータの全体ブロブ)「メッセージ」を送信するための3つの標準オプションがあります。

  • 接続ごとに1つのメッセージ:あなたは検出することができますがメッセージの末尾が接続を終了する
  • 「エンドメッセージ」マーカーの一部:データを読むときに、メッセージの末尾を示す特殊マーカーがあるかどうかをチェックします。あなたは
  • 実際のデータが送信される前に、メッセージのサイズを示すヘッダを読んでとアンエスケープ - - ただ個人的に多くのバイトが

読みマーカーは、自然に発生する可能性がある場合は、それをエスケープする必要があります最後のオプションが好きです。データを読み込んで、最初の2つのオプションよりはるかに単純なものになっていることを確認します。開始する前にデータを受け取るために適切な量のメモリを割り当てることができます。ただし、開始する前にメッセージサイズがわからない場合は、うまく対処できません。 1つのメッセージに対して複数の「チャンク」を設定し、チャンクサイズとデータを送信し、チャンクサイズを0にすると、このスキームを変更できます。あなただけのソケット経由でデータを転送している場合は、その

は注意、あなたはI BASE-64を最初変換しないだろう、それは7ビットクリーンASCIIである必要はありません。バイナリデータとして転送するだけで、コードは時間と帯域の両方でより簡単で効率的になります。

+0

正常に閉じられていない(したがって不完全なファイルとして扱われる)接続を介して完全なファイルが送信されている可能性があります – jgauffin

+0

@jgauffin:TCPは、 、クライアントライブラリ(Javaや.NETなど)はそれに応じて例外をスローします。とにかくそれは私の理解です。 –

+0

アプリケーションレベルのプロトコルを設計するだけです。たとえば、*ファイル情報ヘッダー*を送信します。*にはファイルサイズとファイル内容が含まれます。サーバーがファイルを完全に受信しない場合(たとえば、クライアントが切断された場合)、サーバーはファイルを「不完全」として扱います。 –

0

送信しようとしているバイト数を最初に送信できます。受信側はこれを最初に読み込み、将来、多くのバイトがあることを知っています。

たとえば、ファイルをエンコードし、エンコードされたサイズが800バイトであることを確認します。あなたは800という数字を(例えば4バイトで)送信し、次にファイルを送信します。

受信側は4バイトを読み取り、800を取得してから、ファイル全体を受信するために800バイト以上を読み取ることがわかります。

これは、長さ接頭辞として知られています。

関連する問題