简体   繁体   中英

Multithreading to receive data from multiple UDP clients

I wanted to receive data from different clients(Number of clients is fixed,say 10) ,And each of the clients send data on 5 different predefined ports which wont change.(example, client 1 ports 5000,5001,5002,etc).All the clients can send data simultaneously. (All the above are fixed)

Say in TCP, i can create multiple threads,one for each of the connection we accept ,like the below. UDP is connectionless,So how can we create one thread per UDP client(UDP port) to handle the concurrent data?Like each thread having a receivefrom() function to get data.

//UDP Server

#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;
}

Update I have like 5 ports per client, totally 5 * 10 sockets and data will be sent in time gaps of few milliseconds simultaneously.Here packets received on each port are of different sizes. The packets are sent with Header and CRC. Is it a good idea to have packet numbers in order to track and rerequest the lost packets ?

(or) What are the different ways to track the lost packets and request for them using UDP?

An alternative to threads is select() function, which provides synchronous I/O multiplexing. You can provide your 5 socket fds to the select() function and wait until one of them is ready with data. Rinse and repeat.

Look at the man page: http://linux.die.net/man/2/select or many tutorials on the web.

You do not need multiple threads.

If your bottleneck is IO, threads are not going to help.

If your bottleneck is processing/CPU, accept them all in one thread and then dispatch to several threads.

if you want a thread per port solution: for each port number p create a thread and pass it p as parameter then the thread will do: socket(); bind(p), while (1) { recvfrom(); sendto(); }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM