のための良い例です。大きなファイルをあるストリームから別のストリームにコピーするのはかなり簡単です:
byte[] data = new byte[1024];
while(true) {
int bytesRead = filestream.read(data,0,data.Length);
if (bytesRead==0) break;
netstream.write(data,0,bytesRead);
}
それから、完了したらソケットを閉じてください。
メタデータ(ファイル名やサイズ)を送信したい場合や接続を閉じたくない場合は、これを処理するために何らかのプロトコルが必要です。 FTPは2つの別個のソケットを使用します(メタデータの場合は1つ、データの場合は1つ、これは帯域外通信と呼ばれます)。ファイアウォールがないLANに接続している場合、それは完全に受け入れられる可能性があります。一方、インターネット転送を行いたい場合は、1つのポートをオープンにするのは難しい作業ですが、2つは耐え難いことです。パフォーマンスについてあまり気にしないのであれば、バイトを特定のバイト範囲内にあることを確認するbase64エンコーディングでエンコードすることができます。 base64では、改行や英数字以外の文字でメッセージを区切ることができます。その後、最初のメッセージにはファイル名、サイズなどが含まれ、次に2番目のメッセージとしてデータが送信され、クライアントはそれが完了したことを「全ファイル」メッセージで送信します。
メッセージのもう1つの戦術は、エスケープシーケンスを使用しています。たとえば、バイトストリームを取り出し、 '\ 0'の各インスタンスを '\ 0 \ 0'に置き換えます。 '\ 0 \ 1'を使用してメッセージの終わりを通知します。メッセージの終わりはデータメッセージに含まれないことが保証されています。受信側で '\ 0 \ 0'を '\ 0'に戻します。これはCでもうまくいきますが、実際には各バイトのループはC#でバッファ全体を読み取るよりも遅くなることがあります。
最適な方法は、ある種のアダプティブ長プロトコルを採用することです。例えば、特定のサイズのチャンク(512バイトなど)でデータを送信します。各チャンクの前に、System.BitConverter経由でチャンクのサイズを表す32ビットintを送信します。だから、メッセージは(英語)のようになります。
Here's 512 bytes:
[data]
Here's 512 bytes:
[data]
Here's 32 bytes:
[data]
Here's 4 bytes:
That was the whole file
ここでの利点/バッファが(一度に512のバイトを読み込む)あなたのために働く読んで、あなたがコピーを作ることができるということです、あなたのスループットを意味することは、ネットワーク・スタックによって制限されていますあなたのC#コードの代わりに。クライアントは、次の[data]セグメントに使用するバッファのサイズを知るための固定長の32ビットintを読み込みます。ここで
はそのようなメッセージを書き込むためにいくつかのコードです:
byte[] intbuf = new byte[int_32_size];
int offset = 0;
while (offset < int_32_size)
{
int read = 0;
read = d.plaintextStream.Read(intbuf,offset,int_32_size - offset);
offset += read;
}
int msg_size = System.BitConverter.ToInt32(intbuf,0);
//allocate a new buffer to fill the message
byte[] msg_buffer = new byte[msg_size];
offset = 0;
while (offset < msg_size)
{
int read = 0;
read = d.plaintextStream.Read(msg_buffer,offset,msg_size - offset);
offset += read;
}
return msg_buffer;
ASP.Netクラス?私はWindowsアプリケーションの間で通信を探していました。 –
どういう意味ですか?私が言及するクラスのどれもASP .NETクラスではありません。 – driis