0
votes

I have this server app where clients can connect to. Now i want that when the clients are connected i can send data to all of them. I manage to do it when i connect my two clients.. what i send is received by my two clients. but my problem is when i connect client1 then send data to server, client1 can receive data then i connect client2 and i send data to the server. now when i send data from server to my clients only client1 can receive data but when i disconnect client 1 then client2 can receive data from the server.

How can i make them work at the same time?.. Also how can i make my server accept messages at the same time from my client?..

Here's the part of the code im having trouble.

for(j=0;j<MAX_CLIENTS; j++)
Clients[j].connected_sock = -1;


do
   {

      fduse = fdin;

      printf("Waiting for Connection\n");
      err = select(sMax + 1, &fduse, NULL, NULL, NULL);

      if (err < 0)
      {
     perror("  select() failed");
     break;
      }

      DescRead = err;
      for (SockStorage=0; SockStorage <= sMax  &&  DescRead > 0; ++SockStorage)
      {

      if (FD_ISSET(SockStorage, &fduse))
      {

        DescRead -= 1;


        if (SockStorage == socketFd)
        {
           printf("  Listening socket is readable\n");

           do
           {

              NewSFD = accept(socketFd,(struct sockaddr *) &cli_addr, &clilen);
              if (NewSFD < 0)
              {
                 if (errno != EWOULDBLOCK)
                 {
                    perror("  accept() failed");
                    DCSERVER = TRUE;
                 }
                 break;
              }

                if(ClientCount < MAX_CLIENTS){

                for(loop = 0; loop <MAX_CLIENTS; loop++){

                if(Clients[loop].connected_sock<0){

                Clients[loop].connected_sock = NewSFD;

                break;

                }

              }

              ClientCount++;
              }
              else
              {

              printf("Maximum Client Reached.\n");
              char *sendtoclient = "Server full. ";
              send(NewSFD, sendtoclient, strlen(sendtoclient),0);
              close(NewSFD);
              break;

              }

                ip = ntohl(cli_addr.sin_addr.s_addr);
                printf("  Connection from %d.%d.%d.%d\n",
                    (int)(ip>>24)&0xff,
                    (int)(ip>>16)&0xff,
                    (int)(ip>>8)&0xff,
                    (int)(ip>>0)&0xff);
                    dlogs(ip);


              FD_SET(NewSFD, &fdin);
              if (NewSFD > sMax)
                 sMax = NewSFD;

           } while (NewSFD != -1);


        }

        else
        {

        int d;
        for(d=0; d<MAX_CLIENTS; d++){

        printf("Descriptor ID: %d\n", Clients[d].connected_sock);

        }


          pfds[0].fd = fd;
          pfds[0].events = POLLIN;
          pfds[1].fd = SockStorage;
          pfds[1].events = POLLIN;
          state = FALSE;

           do
           {
            rc = poll(pfds, 2, -1);

            if (pfds[0].revents & POLLIN)
             {

              while ((nbytes = read(fd, buf, sizeof(buf)-1)) > 0)
               {

                      buf[nbytes] = '\0';
                     printf("%s\n", buf);

                   }

              pfds[0].events = 0;
              pfds[1].events = POLLIN | POLLOUT;

               }

            if (pfds[1].revents & POLLIN)
            {
              err = recv(SockStorage, strbuf, sizeof(strbuf), 0);
              if (err < 0)
              {
                 if (errno != EWOULDBLOCK)
                 {
                    perror("  recv() failed");
                    state = TRUE;

                 }
                 break;
              }

               if (err == 0)
              {
                 printf("  Connection closed\n");
                 state = TRUE;

                 break;
              }

              dSize = err;
              printf("  %d bytes received\n", dSize);
            }


            if (pfds[1].revents & POLLOUT)
            {

             int s;
             for(s=0; s<MAX_CLIENTS; s++){

                if(Clients[s].connected_sock>0){

                err = send(Clients[s].connected_sock, buf, strlen(buf), 0);

              if (err < 0)
              {
                 perror("  send() failed");


                 state = TRUE;

                 break;
              }

                }

            }
            pfds[0].events = POLLIN;
            pfds[1].events = POLLIN;
            }


           } while (TRUE);

Here's how im sending data to my clients.

 int s;
             for(s=0; s<MAX_CLIENTS; s++){

                if(Clients[s].connected_sock>0){

                err = send(Clients[s].connected_sock, buf, strlen(buf), 0);

              if (err < 0)
              {
                 perror("  send() failed");


                 state = TRUE;

                 break;
              }

                }

            }

Thanks,

1
Create a separate thread for each socket connection - mathematician1975
yes you should have a seperate thread fore every accept. You can read pthread library. - Raj
Hmmm okay.. but is there any library for that is can be use in socket like asynchronous I/O so i can read and write at the same time to the clients? - demic0de
Separate thread for every connection only if necessary; not mandatory. - SparKot
If you create a lot of threads, know that it will destroy the performance of your code. Select based loops can handle tens of thousands of clients on the most modest of hardware, thread based servers can handle hundreds, or maybe a thousand if well written and running on powerful hardware. - christopher

1 Answers

0
votes

There are generally couple of possible solutions:

  1. You can use separate threads for each client connection;
  2. You can use select;
  3. You can use poll;
  4. You can use epoll;

In Windows environment there are also some other possibilities like IOCP for example.

Each of mentioned solutions have some pros and cons (you need generally distinguish between simplicity and performance).

You can read some network programming tutorial for more details, e.g. this.