4

クライアント要求を処理し、接続されている各サーバーに対して新しいスレッドを作成するマルチスレッド サーバーがあります。これは問題なく機能しており、「テキスト」メッセージをサーバーとの間で問題なく送受信できます。チャットシステムのようです。

今、私はこれらのクライアント接続を介してサーバーにファイルを送信できる方法を念頭に置いていますが、Javaで見られるすべての例には、サーバー/クライアント側で常にハードコードされたファイル名があります-しかし、私は自分自身を設定したいです柔軟性のために。そして、ファイルを受信するだけでなく、同じポートで「テキスト」メッセージを同時に受信できるようになれば幸いです。

私が現在持っている「テキスト」メッセージポートが、クライアントからファイルが送信されることをサーバーに伝え、サーバーがファイル転送専用の「ファイル転送」ポートを開くという考えがあります。そうすれば、「テキスト」ポートでファイルの名前などを指定できます。そして、もう一方のポートは、中断することなく、ファイルを問題なく送信できました。

しかし、これを行うためのより良い方法を知っている人はいますか? 2 つのポートを使いたくないのですが、少し面倒です。サーバー側で別のスレッドを作成して、ファイル転送を処理し、同時に「テキスト」メッセージを処理したいのですが、可能であれば?

前もって感謝します、私は十分に明確であることを願っています:)

4

5 に答える 5

4

確かに、それは簡単です。最初にメッセージタイプを指定する必要があります。バイトまたはテキスト行のいずれかを使用します。

最も簡単な方法は、次のような1バイトを使用することです。

//to send
Socket s = ...
OutputStream os = s.getOutputStream();
if(messageIsText()){
  os.write(0);
  //send text
else{
  os.write(1); 
  //send file
}

次に、サーバーでこれを行うことができます。

Socket s = serverSocket.accept();
InputStream in = s.getInputStream();
int firstbyte = in.read();
if(firstbyte = 0){
   //read text
}
else{
   //read file
}

さて、それはあまり柔軟ではありませんが、あなたができることはたくさんあります。実際には、HTTPの仕様であるRFC2616を読むことをお勧めします。すべてを読む必要はなく、単純なWebサーバーを作成するのに十分です。それは実際には本当に簡単です(HTTPはコアで本当にシンプルなプロトコルですが、現在は多くの高度な機能を備えています)

本当にネットワークプログラミングを学びたいのなら、HTTPサーバーを書いてみてください。それは気が遠くなるように聞こえるかもしれませんが、心配しないでください。実際にはそれほど難しくはありません。

于 2010-01-25T14:19:37.123 に答える
1

FTP を再発明しているようですね。Java で実装された FTP サーバーを見たいと思うかもしれません。WebDAVも。

于 2010-01-25T14:11:32.267 に答える
0

ファイルをバラバラにして、「通常の」行に沿って送信します。

何かリンク:

  • メール
  • 開始ファイル (id <-- クライアントによって作成された ID 番号、ファイル名)
  • ファイルピース (id、byte[] にいくつかのバイトを含む)
  • 最終ファイル (id)

サーバーは開始ファイルを受信し、新しい構造の保存を開始します。

次に、各ファイルピースにそのバイトを追加します(おそらくディスクまたは何かに書き込む)

最終ファイル meesage は次のように言うでしょう: OK、フラッシュして閉じます!

サーバーは、Key オブジェクト (clientid+fileid) から一時構造体にマッピングして、ファイルをマップに保存できます。

于 2010-01-25T14:09:51.443 に答える
0

あなたが説明することは、FTP がどのように機能するかということです。そして、そうです、特にサーバーがポートを開く部分は厄介です。これは、この時代のファイアウォールと NAT では機能しないためです。したがって、FTP は、クライアントが追加のポートを開く「パッシブ モード」を追加する必要がありました。

しかし、別々のポートを持つ理由はまったくありません。「ここにファイルがあります」と通知する 1 種類のテキスト メッセージを単純に用意し、その直後に同じポートでファイルを送信しないのはなぜですか?

于 2010-01-25T14:12:45.290 に答える
0

さて、2 つのオプションがあります。アウトオブバンド転送 (FTP のように、ええ、上記の連中はすでにそう言っていました)、またはインターリーブ ストリーミングを行うことができます。たとえば、クライアントでタイプ/サイズ ヘッダーをストリームに発行し、ファイル セグメントまたはテキスト メッセージ (対応するバイト長) をダンプします。サーバー上では、接続スレッドごとに 1 つのスレッドを介してファイル セグメントの読み取り/書き込みを行いながら、中央のコンシューマー スレッド (接続スレッドごとに 1 つの非同期プロデューサー) でテキスト メッセージを処理することができます。

そのクールなインターリーブのために、Google protobuf ライブラリのいずれかを試すことができます - それらには、データの小さなチャンクをストリームに読み書きするための優れたプリミティブ、またはプレーン/古いObject(In|Out)putStream があります。

于 2011-02-11T18:23:08.540 に答える