2012-03-12 11 views
0

新しい接続が到着したサーバーがこの接続を受け入れ、最近サーバーに接続したクライアントにサービスするための新しいプロセスを作成すると、サーバーはクライアントからの新しい接続要求を頻繁に待つファイルダウンロードアプリケーションに取り組んできました。クライアントはサーバーから複数のファイルをダウンロードするよう要求できます。各ファイルについて、クライアント側とサーバー側は新しいスレッドを作成し、各ファイルのデータ転送は、サーバーとクライアントの適切なスレッド結合の間で実行する必要があります。私はスレッドのためにCとpthreadを使用しています。私は安定したソケット接続と各クライアントのための成功したプロセス作成が今のところあります。次のようにアプリケーションのようなクライアント/サーバーのスレッド同期?

は、ねじファイルランサーのために、私は試みを持っていた:私は同じ作成、サーバ側で同様

 int k; 
     for (k = 0; k < fNameCounter; k++) 
     { 
      pthread_t thread_id; 
      int status = pthread_create(&thread_id, NULL, &receiveFile, fName); 

      if (status != 0) 
      { 
       printf("Thread Creation Failed \n"); 
       exit(0); 
      } 
     } 

をクライアントでは、私は、ファイルを受信するための方法を実行しているスレッドを作成していますスレッドの数は、次のように:あなたがpthread_createの中で見ることができるよう

 int k; 
     for (k = 0; k < fnameCounter; k++) 
     { 
      pthread_t thread_id; 
      int status = pthread_create(&thread_id, NULL, &sendFile, fName); 

      if (status != 0) 
      { 
       printf("Thread Creation Failed \n"); 
       exit(0); 
      } 
     } 

SENDFILEとreceiveFile機能を単にfNameを(で指定されたファイルのバイトを書き込み、読み込み、 )ソケットによって、その時点で私は大きな問題があります:

これまでのプログラムでは、すべてのスレッドがサーバーからのデータの受信を完了した後にファイルの内容が異なる可能性があります。sendFile readFile関数はソケットから読み込んでソケットに書き込みます。

は、どのように私は、以下に説明するように、クライアントの各スレッドは、サーバの適切なスレッドから適切なデータを取得することを保証することができます

 receive   send 

cthread1 ----> a.txt <----- sthread1 

cthread1 ----> a.txt <----- sthread1 

cthread1 ----> a.txt <----- sthread1 

P.S.を私は、1つのソケットに多くのスレッドを作成することは意味がありませんが、それは私のhwだと私はそうする必要があることを知っている:/。

よろしくお願いいたします。

答えて

1

最も簡単な方法は、ファイルごとに新しいソケットを開くことです。

0

zvrba非常に有効なポイント(1つのソケット、1つのファイル)を完成させる。

ここではスレッドは役に立たないと思う:ネットワークカードが1つある。あなたは同じリソースを何度も聞いてより速くなることはありません。あなたは実際にあなたのスレッドがお互いをブロックし、実際には遅くなる可能性が高いです。

ユーザーにフィードバックを与えたい場合は、すべてのソケットIOに対して1つのバックグラウンドスレッドを作成することができます。

selectを使用して同じスレッド内のいくつかの接続を処理して、読み書きできるソケットを検出する必要があります。

+0

実際には、コースプロジェクトですので、そのようにする必要があります。また、私はそれは各クライアントのために1つのソケットから提供されますが、私は選択肢がないのでスレッドを使用する無意味であることを知っている:)と本当にその同期の問題に立ち往生。 – StM

+0

質問を編集して制約を明確にしてください:単一のソケットと両側に多数のスレッドを使用して多数のファイルを並列に送信してください。これは譲渡であり、効率的な条件は交渉可能ではないことに言及する。 –

0

1つのソケットの制限を考慮すると、送信されるバイトにいくつかのヘッダー情報を追加することができます。このヘッダーには、そのビットの情報の原因となるスレッドのペアに関する情報が含まれている場合があります。

たとえば、sthread1は、ファイルa.txtから100バイトを送信します。数字の1を含む1バイトをそのストリームの先頭に追加することができます。そのチャンクのデータを受信すると、cthread1は最初のバイトをチェックする必要があります。1であればOK、このチャンクはcthread1であり、処理を続行します。ヘッダーが1でない場合、cthread1はこのチャンクを無視し、他のスレッドも実行する機会を与えて待機してください。する必要があります。

データのチャンクを特定できない場合、どのスレッドがどのチャンクを処理するかを判断することは不可能です。

これはに対処するための複雑さの多くを追加することに注意してください。

  1. あなたは
  2. あなたは1バイトのみを使用している場合は、中保つスレッドのあなたのペアにこれらの識別子を割り当てる方法を決定する必要があります
  3. recv関数内のフラグMSG_PEEKcthreadの中に使用する必要があるかもしれません(必要に応じてチャンクを無視することができます)。このフラグは、関数recvの動作を変更します。 this(Winでプログラミングしている場合)またはthis(Linuxの場合)を読むことをお勧めします。