1

これは教育目的(大学の割り当て)です。

Linux用のCでクライアントサーバープログラムを作成する必要があります。(私はすでにその部分を持っています。クライアントはサーバーに接続し、問題なくファイルを送受信します...)。

クライアントがサーバーに接続すると、クライアント上のファイルのリストがサーバーに送信されます。したがって、サーバーには、クライアント上のすべてのファイルのリストがあります。

クライアントAはサーバーにファイル「test.txt」を要求できます。サーバーはファイルがクライアントBにあることを認識しており、ファイルをBからAに転送する必要があります。私は最善の方法を考えています。これ。

  1. Bからバッファに受信し、すぐにバッファをAに送信しますか?
  2. Bからのファイル全体をrecv()してサーバーに保存し、Aに送信しますか?

私のプログラムはこの動作をサポートする必要があります。AがBにファイルを要求し、次にCがBにファイルを要求した場合、Cは転送A<->Bが終了するまで待機しないでください。そして、これは私が立ち往生しているところです。

どうもありがとうございます!!

編集:私のサーバーはスレッドを使用しています:新しいクライアントが接続しているときはいつでも、それを提供するために新しいスレッドが開かれます。私のクライアントは、現時点ではスレッドを使用していません(これは変更できます)。

4

3 に答える 3

1

ソケットを使用して一度に複数の転送を行いたい場合は、次の 2 つのオプションがあります。

ソケットとスレッドのブロック

これは、サーバーを作成した方法です。スレッドの問題は、デバッグがかなり難しいバグにつながる可能性があることです。それ自体をデバッグするのがかなり難しい可能性があるネットワークのバグと組み合わせると、悪夢のようなデバッグ セッションが発生する可能性があります。

ノンブロッキング ソケットと select()

この方法はスレッドを必要とせず、代わりに select() を使用して、どのソケットに読み取り待ちのデータがあるかを確認します。それをいくつかのループと組み合わせると、複数のファイルを同時に転送できます。ソケットをブロックしないように設定するのは簡単です。正しい方法を使用するのは少し難しいかもしれませんが、スレッドとネットワークのバグの可能性を考慮すると、これは私が個人的に好むネットワーク コードの記述方法です。

あなたの実際の問題について; 私は次のようなことを提案します:

Client A connects to server S. You need to bind the local side for the next step.
A also opens another socket for data transfer on the next port upwards.
S sends file list to A. How you build up the file list I leave to you.
A requests file F from S.
S checks which client has F.
S sends "send F to A on port X" to B. You can check which remote port is used, and then you know which port to send the file on.
B recieves and executes the command.
于 2012-12-21T09:34:35.297 に答える
0

これまでに得たもの: サーバーは select() でのみ実行されています。クライアントには listen() モードのソケットがあります。それを dataSocket (通常のソケットの上) と呼びます。クライアント A がファイルを必要とする場合、サーバーにファイル名を伝えます。サーバーはファイルを持っているユーザーを見つけ、dataSocket に対して connet() を作成します。(私はそれを実装することができました)。

小さなファイルは問題なく転送されます。大きなファイルは失敗します。

それは私のクライアントに何か問題があるからだと思います。select() 関数を使用してクライアントを実装しました。connect() を実行している人が見つかった場合は、新しいスレッドを開いてリクエストを処理します。しかし、何かが間違っています..コードは次のようになります:

FD_SET(globalSocket,&origin);
FD_SET(dataSocket,&origin);
FD_SET(STDIN,&origin); //#define STDIN 0
while(1)
{
 readfds=origin;
 select(fdmax+1,&readfds,NULL,NULL,NULL);
 for(i=0;...)
  {
   if(FD_ISSET(i,&readfds)
   {
    if(i==STDIN)
     // get user input
    if(i==dataSocket)
     {
      printf("someone wants a file from me");
      pthread_create(...);
     }
   }
  }
}

私が見た問題の 1 つは、ファイルの最初の要求を行うときに、「someone want a file from me」という行が 2、3 回表示されますが、作成されるスレッドは 1 つだけです。そして、大きなファイルを送信しようとすると、一部は取得されますが、「ピアによって接続がリセットされました」というメッセージが表示されます...

ここにいる誰かが、説明が不十分な私の質問に答えてくれることを願っています。ありがとうございました。

于 2012-12-21T18:34:32.827 に答える
0

クライアントごとに 2 つのソケットを接続する必要があるため、次のように 4 つのソケットが必要になります。

1 A <-> C
2 B <-> C 
3 A <-> C <-> B 4

したがって、クライアント A とサーバー C (ソケット 1) 間、およびクライアント B とサーバー C (ソケット 2) 間でファイルを転送するには、ソケット 1 と 2 を使用する必要があります。

次に、ソケット 3 と 4 を使用してサーバー C でブリッジを開発し、A から B にデータを転送する必要があります。

マルチスレッドソリューションが機能するはずです。

于 2012-12-21T09:04:38.200 に答える