2

さまざまなクライアントからデータを受信したかった (クライアントの数は固定、たとえば 10)。各クライアントは、変更されない 5 つの異なる定義済みポートでデータを送信します (たとえば、クライアント 1 ポート 5000、5001、5002 など)。すべてのクライアントが同時にデータを送信できます。(上記はすべて修正済み)

TCP で言うと、次のように、受け入れる接続ごとに 1 つずつ、複数のスレッドを作成できます。UDP はコネクションレスです。では、同時データを処理するために UDP クライアント (UDP ポート) ごとに 1 つのスレッドを作成するにはどうすればよいでしょうか? 各スレッドが receivefrom() 関数を使用してデータを取得するように。

//UDP サーバー

#define BUFLEN 512

#define CLIENT1_PORT1 5000
#define CLIENT1_PORT2 5001
#define CLIENT1_PORT3 5002

#define CLIENT2_PORT1 5050
#define CLIENT2_PORT2 5051
#define CLIENT2_PORT3 5052  

#define CLIENT3_PORT1 6000
#define CLIENT3_PORT2 6001
#define CLIENT3_PORT3 6002

void diep(char *s) {
  perror(s);
  exit(1);
}

int main(void) {
  struct sockaddr_in client1_sockaddr_1, client1_sockaddr_2,client2_sockaddr_1,client2_sockaddr_2, si_other;
  int c1_sockfd_1,c1_sockfd_2, c2_sockfd_1,c2_sockfd_2, i, slen = sizeof(si_other);

  char buf[BUFLEN];

  /******for client 1 port1 **********/
  if((c1_sockfd_1 = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    diep("socket");

  memset((char *) &client1_sockaddr_1, 0, sizeof(client1_sockaddr_1));

  client1_sockaddr_1.sin_family = AF_INET;
  client1_sockaddr_1.sin_port = htons(CLIENT1_PORT1);
  client1_sockaddr_1.sin_addr.s_addr = htonl(INADDR_ANY);

  if(bind(c1_sockfd_1, (struct sockaddr *) &client1_sockaddr_1, sizeof(client1_sockaddr_1)) == -1)
    diep("bind");

  if((c2_sockfd_1 = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    diep("socket");

  /*******for client 2 port1 *******/
  memset((char *) &client2_sockaddr_1, 0, sizeof(client2_sockaddr_1));

  client2_sockaddr_1.sin_family = AF_INET;
  client2_sockaddr_1.sin_port = htons(CLIENT2_PORT1);
  client2_sockaddr_1.sin_addr.s_addr = htonl(INADDR_ANY);

  if(bind(c1_sockfd_2, (struct sockaddr *) &client2_sockaddr_1, sizeof(client2_sockaddr_1)) == -1)
    diep("bind");

//Receive from clients
while(1) {

  /*How to create threads at this point and have a separate recvfrom for each client port ??*/
  if(recvfrom(c1_sockfd_1, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == -1)
      diep("recvfrom()");

    printf("Recieved packet from %s: %d\nData: %s\n\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);
  }
  close(c1_sockfd_1);
  return 0;
}

更新 クライアントごとに 5 つのポート、合計 5 * 10 ソケットがあり、データは数ミリ秒のタイム ギャップで同時に送信されます。ここで、各ポートで受信されるパケットのサイズは異なります。パケットはヘッダーと CRC とともに送信されます。失われたパケットを追跡して再要求するために、パケット番号を取得することは良い考えですか?

(または) 失われたパケットを追跡し、UDP を使用してそれらを要求するさまざまな方法は何ですか?

4

3 に答える 3

3

スレッドの代わりに、同期 I/O 多重化を提供する select() 関数があります。5 つのソケット fd を select() 関数に提供し、そのうちの 1 つがデータの準備ができるまで待つことができます。すすいで繰り返します。

man ページを見てください: http://linux.die.net/man/2/selectまたは Web 上の多くのチュートリアル。

于 2013-03-30T00:11:34.463 に答える
1

ポート ソリューションごとのスレッドが必要な場合: ポート番号ごとに p スレッドを作成し、それをパラメーターとして p に渡すと、スレッドは次のようになります。bind(p), while (1) { recvfrom(); に送る(); }

于 2013-03-30T11:45:21.793 に答える
1

複数のスレッドは必要ありません。

ボトルネックが IO である場合、スレッドは役に立ちません。

ボトルネックが処理/CPU である場合は、それらをすべて 1 つのスレッドで受け入れてから、複数のスレッドにディスパッチします。

于 2013-03-28T18:35:50.693 に答える