title: Asynchronous C client for a multiclient C server
body: <p>I have a client which is working fine, but whenever I run a new client, sometimes I don't receive the sent message on the other client already running, while using telnet it works flawlessly, the message "broadcasts" to all connected clients, and I want whenever a message is received to one of the clients to show even if I didn't already send a message.
  Should I use select on clients ? and what should be changed ?</p>
  
  <p>client.c:</p>
  
  <pre><code>#include &lt;stdio.h&gt; //printf
  #include &lt;string.h&gt;    //strlen
  #include &lt;sys/socket.h&gt;    //socket
  #include &lt;arpa/inet.h&gt; //inet_addr
  #include &lt;unistd.h&gt; 
  
  int main(int argc , char *argv[]){
      int sock;
      struct sockaddr_in server;
      char message[256] , server_reply[256];
  
      //Create socket
      sock = socket(AF_INET , SOCK_STREAM , 0);
      if (sock == -1)
      {
          printf("Could not create socket");
      }
      puts("Socket created");
  
      server.sin_addr.s_addr = inet_addr("127.0.0.1");
      server.sin_family = AF_INET;
      server.sin_port = htons( 9034 );
  
      //Connect to remote server
      if (connect(sock , (struct sockaddr *)&amp;server , sizeof(server)) &lt; 0){
          perror("connect failed. Error");
          return 1;
      }
  
      puts("Connected\n");    
  
      //keep communicating with server
      for(;;){
  
      printf("Enter message: ");
      memset(message, 0, 256);
      fgets(message, 256,stdin);
      // scanf("%s" , message);
  
          //Send some data
          if( send(sock , message , strlen(message) , 0) &lt; 0)
          {
              puts("Send failed");
              return 1;
          }
  
          //Receive a reply from the server
          if( recv(sock , server_reply , 256 , 0) &lt; 0)
          {
              puts("recv failed");
              break;
          }
  
      printf("Server Reply: %s\n", server_reply);
      server_reply[0]='\0'; 
      }
  
      close(sock);
      return 0;
  }
  </code></pre>
  
  <p>server.c:</p>
  
  <pre><code>/*
  ** selectserver.c -- a cheezy multiperson chat server
  */
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;netdb.h&gt;
  
  #define PORT "9034"   // port we're listening on
  
  // get sockaddr, IPv4 or IPv6:
  void *get_in_addr(struct sockaddr *sa)
  {
      if (sa-&gt;sa_family == AF_INET) {
          return &amp;(((struct sockaddr_in*)sa)-&gt;sin_addr);
      }
  
      return &amp;(((struct sockaddr_in6*)sa)-&gt;sin6_addr);
  }
  
  int main(void){
      fd_set master;    // master file descriptor list
      fd_set read_fds;  // temp file descriptor list for select()
      int fdmax;        // maximum file descriptor number
  
      int listener;     // listening socket descriptor
      int newfd;        // newly accept()ed socket descriptor
      struct sockaddr_storage remoteaddr; // client address
      socklen_t addrlen;
  
      char buf[256];    // buffer for client data
      int nbytes;
  
      char remoteIP[INET6_ADDRSTRLEN];
  
      int yes=1;        // for setsockopt() SO_REUSEADDR, below
      int i, j, rv;
  
      struct addrinfo hints, *ai, *p;
  
      FD_ZERO(&amp;master);    // clear the master and temp sets
      FD_ZERO(&amp;read_fds);
  
      // get us a socket and bind it
      memset(&amp;hints, 0, sizeof hints);
      hints.ai_family = AF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_flags = AI_PASSIVE;
      if ((rv = getaddrinfo(NULL, PORT, &amp;hints, &amp;ai)) != 0) {
          fprintf(stderr, "selectserver: %s\n", gai_strerror(rv));
          exit(1);
      }
  
      for(p = ai; p != NULL; p = p-&gt;ai_next) {
          listener = socket(p-&gt;ai_family, p-&gt;ai_socktype, p-&gt;ai_protocol);
          if (listener &lt; 0) { 
              continue;
          }
  
          // lose the pesky "address already in use" error message
          setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &amp;yes, sizeof(int));
  
          if (bind(listener, p-&gt;ai_addr, p-&gt;ai_addrlen) &lt; 0) {
              close(listener);
              continue;
          }
  
          break;
      }
  
      // if we got here, it means we didn't get bound
      if (p == NULL) {
          fprintf(stderr, "selectserver: failed to bind\n");
          exit(2);
      }
  
      freeaddrinfo(ai); // all done with this
  
      // listen
      if (listen(listener, 10) == -1) {
          perror("listen");
          exit(3);
      }
  
      // add the listener to the master set
      FD_SET(listener, &amp;master);
  
      // keep track of the biggest file descriptor
      fdmax = listener; // so far, it's this one
  
      // main loop
      for(;;) {
          read_fds = master; // copy it
          if (select(fdmax+1, &amp;read_fds, NULL, NULL, NULL) == -1) {
              perror("select");
              exit(4);
          }
  
          // run through the existing connections looking for data to read
          for(i = 0; i &lt;= fdmax; i++) {
              if (FD_ISSET(i, &amp;read_fds)) { // we got one!!
                  if (i == listener) {
                      // handle new connections
                      addrlen = sizeof remoteaddr;
                      newfd = accept(listener,
                          (struct sockaddr *)&amp;remoteaddr,
                          &amp;addrlen);
  
                      if (newfd == -1) {
                          perror("accept");
                      } else {
                          FD_SET(newfd, &amp;master); // add to master set
                          if (newfd &gt; fdmax) {    // keep track of the max
                              fdmax = newfd;
                          }
                          printf("selectserver: new connection from %s on "
                              "socket %d\n",
                              inet_ntop(remoteaddr.ss_family,
                                  get_in_addr((struct sockaddr*)&amp;remoteaddr),
                                  remoteIP, INET6_ADDRSTRLEN),
                              newfd);
                      }
                  } else {
                      // handle data from a client
                      memset(buf, 0, 256);
                      if ((nbytes = recv(i, buf, sizeof buf, 0)) &lt;= 0) {
                          // got error or connection closed by client
                          if (nbytes == 0) {
                              // connection closed
                              printf("selectserver: socket %d hung up\n", i);
                          } else {
                              perror("recv");
                          }
                          close(i); // bye!
                          FD_CLR(i, &amp;master); // remove from master set
                      } else {
                          // we got some data from a client
                          for(j = 0; j &lt;= fdmax; j++) {
                              // send to everyone!
                              if (FD_ISSET(j, &amp;master)) {
                                  // except the listener and ourselves
                                  if (j != listener &amp;&amp; j != i) {
                                      if (send(j, buf, nbytes, 0) == -1) {
                                          perror("send");
                                      }
                                  }
                              }
                          }
                      }
                  } // END handle data from client
              } // END got new incoming connection
          } // END looping through file descriptors
      } // END for(;;)--and you thought it would never end!
  
      return 0;
  }
  </code></pre>