3

それぞれが 5 つの異なるポートで送信する 15 の異なるクライアントからデータを受信する必要があります。全部で 15 *5 ソケット。

各クライアント ポート番号が定義され、固定されています。例クライアント1、ポート3001から3005。クライアント2、ポート3051から3055など。最初のポート(3001、3051)がコマンドの送信に使用されるという共通点があります。他のポートはデータを送信します。

データを受信したら、チェックサムを確認する必要があります。recvd パケットを追跡し、失われた場合はパケットを再要求し、ハードディスク上のファイルに書き込む必要もあります。

制限上記の設計を変更することはできません。また、UDP から TCP に変更することもできません。読んだ後に私が知っている2つの方法は

  • select() を使用した非同期多重化。
  • ソケットあたりのスレッド。

私は最初のものを試しましたが、データを取得した時点で立ち往生しています。データを受信できました。私はいくつかの処理を行う必要があるので、ソケットごとに (または) ソケットを処理するためにスレッドを開始したい (たとえば、すべての最初のポート、すべての 2 番目のポートなど..ie3001、3051 など) しかし、ここでクライアントがデータを送信すると、FD_ISSET は次のようになります。 true 、スレッドを開始すると、すべてのメッセージのスレッドになります。 質問: ここにスレッド コードを追加する方法です。たとえば、if(FD_ISSET ..) 内に pthread_create を含めると、受信したメッセージごとにスレッドを作成します。しかし、ソケットごとにスレッドが必要でした。

  while(1)
   {
      int nready=0;
      read_set = active_set;

      if((nready = select(fdmax+1,&read_set,NULL,NULL,NULL)) == -1)
      {
        printf("Select Errpr\n");
        perror("select");
        exit(EXIT_FAILURE);
      }
      printf("number of ready desc=%d\n",nready);

      for(index=1;index <= 15*5;index++)
      {
         if(FD_ISSET(sock_fd[index],&read_fd_set))
         {              
           rc = recvfrom(sock_fd[index],clientmsgInfo,MSG_SIZE,0,
                    (struct sockaddr *)&client_sockaddr_in,
                      &sockaddr_in_length);
           if(rc < 0)
               printf("socket %d down\n",sock_fd[index]);

           printf("Recieved packet from %s: %d\nData: %s\n\n", inet_ntoa(client_sockaddr_in.sin_addr), ntohs(client_sockaddr_in.sin_port), recv_client_message);                                      
                }
         } //for
     } //while
4

3 に答える 3

0

ソリューションには、一定数の比較的少数の接続が必要です。

recvfrom()5 つのポートのそれぞれをリッスンして でブロックし、データを処理して、再度ブロックするスレッド プロシージャを作成するヘルプ プロシージャを作成します。その後、ヘルパーを 15 回呼び出してスレッドを作成できます。

これにより、すべてのポーリングが回避され、Linux が I/O の完了時に各スレッドをスケジュールできるようになります。待機中に CPU は使用されず、これはやや大規模なソリューションに拡張できます。

大規模なスケーリングが必要な場合は、単一のポート セットを使用して、client_sockaddr_in構造からパートナー アドレスを取得してください。処理にかなりの時間がかかる場合は、スレッドのプールを利用可能な状態に保ち、メッセージを受信するたびに新しいプールを割り当て、その後メッセージの処理を続行し、応答後にスレッドをプールに戻すことで、処理を延長できます。送信されます。

于 2013-04-07T18:57:24.633 に答える