2009-08-09 5 views
6

C#アプリケーションは、同じネットワーク上の別のコンピュータに存在するインスタンスと簡単に通信し、ファイルとデータを転送するにはどうすればよいですか?C#アプリケーションでネットワーク上のファイルを簡単に通信して転送するにはどうすればよいですか?

ネットワーク上のコンピュータが固定ローカルIPアドレスを持ち、それぞれが互いのIPを知っていると仮定します。 IPが不明な場合は、通信する方法もありますか?いくつかの発見プロトコルに基づいて?

アップルの「Bonjour」サービスが良いプロトコルだと聞きました。私たちはWindowsアプリケーションからそれを介して通信できますか?または、「ソケット」を使用する必要がありますか?私は主に自分のニーズを容易に満たすことができるライブラリやサンプルコードを探しています。自分のTCPベースのプロトコルや何かハードコアを開発したくありません。

答えて

2

ファイル/データの転送には、/TcpListenerクラスを使用できます。これは、グリッターのソケット機能に優れる抽象クラスです。または、アプリケーションがより簡単で便利な場合は、HttpListenerクラスを使用してアプリケーションをHTTPサーバーとして使用することもできます。

発見のために、中央サーバーを持つことができます。起動時に各クライアントをサーバーに接続させ、自分自身を登録し、他のオンラインクライアントとそのIPのリストを取得することができます。後続の通信は、クライアント間で直接行うことができます。

このスキームの変形は、中央サーバをプロキシとして動作させ、クライアント間のすべてのトラフィックを通過させることです。これは、クライアントが同じネットワーク上にない場合(ファイアウォールやシナリオでは必要ない)、ファイアウォールやルーティングの問題を克服するために役立ちます。

+0

ASP.Netクラス?私はWindowsアプリケーションの間で通信を探していました。 –

+0

どういう意味ですか?私が言及するクラスのどれもASP .NETクラスではありません。 – driis

2

のための良い例です。大きなファイルをあるストリームから別のストリームにコピーするのはかなり簡単です:

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; 
1

をあなたにもあるファイル同期プロバイダーを見てみたいことがあり、ファイルをコピーするには:

 logger.logger.debug("Sending message of length " + length); 
     byte[] clength = System.BitConverter.GetBytes(buffer.Length); 
     plaintextStream.Write(clength,0,clength.Length); 
     plaintextStream.Write(buffer,0,buffer.Length); 
     plaintextStream.Flush(); 

そして、ここではそれらを読むためにいくつかのコードですMicrosoft Sync Frameworkの一部です。 http://msdn.microsoft.com/en-us/sync/bb887623

関連する問題