cserverclient

C chat. Connect() waits for too long; server can't send particular info to a client


I work on a Wi-Fi multi-user chat program. I'd appreciate some help with the following.

  1. Due to the dhcp nature of routers, it's not clear what address the server machine would get each day. Client goes through the list of all possible hosts, starting with 192.168.1.1. When it encounters a non-server device it waits for a random amount of time, up to a minute. How can I make it stop waiting after a second? I tried stopping it with alarm() before I read alarm manual so it was a waste of time.
  2. Server function printUsers() is the only function whose output is sometimes delivered, sometimes not. I'd love to have someone explain why.
  3. I'd like to have some feedback on general code quality. By that I mean things like code readability and maintainability, program design, style, error handling, etc.

Server Code

#include <arpa/inet.h>
#include <ctype.h>
#include <ifaddrs.h>
#include <netdb.h>       //adds symbolic network constants
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define BYE           0
#define ERROR         -1
#define HOST_SIZE     4
#define MAX_CONN      11
#define MSG_LEN       255
#define NAME_LEN      30
#define SYS_MSG_LEN  18

int debug;            //command-line argument
int mySock;           //sustains value from assignment till the end
typedef struct pollfd pollfd; 

void addName2msg(char name[], char msg[], char msgOut[]);
void addUser(char name[], int i, char msg[], pollfd *fds, int fdsInd);
void findMyIP(char myIP[]);
void handleArgs(int argc, char *argv[]);
void handleLeaver(int i, char names[][NAME_LEN], pollfd *fds, int*fdI);
void handleNewClient(pollfd *fds, int *fdsInd);
void printUsers(char names[][NAME_LEN], int i, int fd);
void sendAll(int i, char msgOut[], pollfd *fds, int fdsInd);
void sendErr(char *msg);
void sendMsg(int fd, char msg[], int len);
void startHost(char myIP[]);


void workLoop()
{
    static pollfd fds[MAX_CONN];
    int status, fdsInd = 0; 
    static char names[MAX_CONN+1][NAME_LEN];
    char msg[MSG_LEN], msgOut[MSG_LEN+NAME_LEN]; 

    fds[fdsInd].fd = mySock;
    fds[fdsInd++].events = POLLIN;

    while(1) {
        if (debug)
            puts("Waiting for an event to happen...");
        if (poll(fds, fdsInd, -1) == -1)
            sendErr("poll() failed");
        if (debug)
            puts("An event happened");
        for (int i = 0; i < fdsInd; i++) {
            if ((fds[i].fd == mySock) && (fds[i].revents & POLLIN)) {
                handleNewClient(fds, &fdsInd);
            } else if (fds[i].revents & POLLIN) { //handle message
                status = recv(fds[i].fd, msg, MSG_LEN, 0);
                if (debug)
                    printf("Recieved msg from %s, socket %d\n", 
                                          names[i], fds[i].fd);

                if ((status == BYE) || (status == ERROR)) {
                    printf("Status is %d\n", status == BYE? BYE: ERROR);
                    handleLeaver(i, names, fds, &fdsInd);
                    continue;
                }
                if (*names[i] == '\0')  {   //no name? Save msg as name
                    addUser(names[i], i, msg, fds, fdsInd);
                    printUsers(names, i, fds[i].fd);
                    continue;
                }
                addName2msg(names[i], msg, msgOut);
                sendAll(i, msgOut, fds, fdsInd);
            }
        }
    }
}


int main(int argc, char *argv[])
{
    char myIP[INET_ADDRSTRLEN];

    handleArgs(argc, argv);
    findMyIP(myIP);              
    startHost(myIP);
    workLoop();

    return 0;
}
//
void addName2msg(char name[], char msg[], char msgOut[]) {
    int len;
    strncpy(msgOut, name, NAME_LEN );
    len = strlen(msgOut);
    msgOut[len] = ':';
    msgOut[len+1] = ' ';
    strcat(msgOut, msg);
}
//
void addUser(char name[], int i, char msg[], pollfd *fds, int fdsInd)
{
    int j;
    char msgWelc[SYS_MSG_LEN + NAME_LEN] = "Welcome to chat, ";
    char msgJoin[SYS_MSG_LEN] = " joined the chat\n";

    for (j = 0; j < NAME_LEN-3; j++) {
        if (msg[j] == '\n' || isspace(msg[j]))
            break;
        name[j] = msg[j];
    }
    name[j] = '\n';
    name[j+1] = '\0';
    strcat(msgWelc, name);
    sendMsg(fds[i].fd, msgWelc, SYS_MSG_LEN+NAME_LEN);
    name[j] = '\0';
    strncpy(msgWelc, name, NAME_LEN);
    strcat(msgWelc, msgJoin);
    sendAll(i, msgWelc, fds, fdsInd);
}
//
void findMyIP(char myIP[])
{
    struct ifaddrs *addrs;
    struct sockaddr_in *pAddr;

    getifaddrs(&addrs);
    for (; addrs != NULL; addrs = addrs->ifa_next) {
        pAddr = (struct  sockaddr_in *) addrs->ifa_addr;
        if (strstr(inet_ntoa(pAddr->sin_addr), "192.168.1") != NULL)
            strncpy(myIP, inet_ntoa(pAddr->sin_addr), INET_ADDRSTRLEN);
    }
    freeifaddrs(addrs);
    if (debug)
        printf("Local IP is %s\n", myIP);
}
//
void handleArgs(int argc, char *argv[])
{
    if (argc > 2) {
        puts("error: one arg max");
        exit(1);
    }
    if ((argc == 2) && (strcmp("-d", argv[argc-1]) != 0)) {
        puts("error: Call with -d for debugging");
        exit(1);
    } else if (argc == 2)
        debug = 1;
}
//
void handleLeaver(
     int i, char names[][NAME_LEN], pollfd *fds, int *fdsInd)
{
    int lastElem = *fdsInd - 1;
    char trash[MSG_LEN];
    char msgLeft[SYS_MSG_LEN] = " left the chat\n";

    //notify all users
    strncpy(trash, names[i], strlen(names[i])+1);   
    strcat(trash, msgLeft);
    sendAll(i, trash, fds, *fdsInd);

    if (debug) {
        printf("Had: fds0:%d fds1:%d fds2:%d; fdsInd: %d\n", 
                    fds[0].fd, fds[1].fd, fds[2].fd, *fdsInd);
        printf("\tNames1: %s, Names2: %s\n", names[1], names[2]);
    }
    recv(fds[i].fd, trash, MSG_LEN, 0);  //receive garbage

    if (lastElem == i) { 
        fds[i].fd = 0;
        fds[i].events = 0;
        (*fdsInd)--;
        names[i][0] = 0;
    } else {           
        fds[i].fd = fds[lastElem].fd;
        fds[i].events = fds[lastElem].events;
        strncpy(names[i], names[lastElem], NAME_LEN);
        fds[lastElem].fd = 0;
        fds[lastElem].events = 0;   
        (*fdsInd)--;
        names[lastElem][0] = 0;
    }
    if (debug) {
        printf("Removed user\n");
        printf("Have: fds0:%d fds1:%d fds2:%d; fdsInd: %d\n", 
                    fds[0].fd, fds[1].fd, fds[2].fd, *fdsInd);
        printf("\tNames1: %s, Names2: %s\n", names[1], names[2]);
    }
}
//
void handleNewClient(pollfd *fds, int *fdsInd)
{
    struct sockaddr clientInfo;
    socklen_t addrSz;
    int newFD; 
    char nameReq[SYS_MSG_LEN] = "Enter your name: ";

    addrSz = sizeof(clientInfo);
    newFD = accept(mySock, &clientInfo, &addrSz); 
    if (*fdsInd > MAX_CONN) {   //kill extra users
        close(newFD);
        return;
    }
    fds[*fdsInd].fd = newFD;
    fds[(*fdsInd)++].events = POLLIN;
    if (debug)
        puts("Accepted a client");
    sendMsg(newFD, nameReq, SYS_MSG_LEN);
}
//
void printUsers(char names[][NAME_LEN], int i, int fd)
{
    int len;
    char msgStart[SYS_MSG_LEN] = "Online Users:\n";
    sendMsg(fd, msgStart, SYS_MSG_LEN);
    if (debug)
        printf("Online users printed for %s, %d\n", names[i], fd);

    for (int j = 0; j < MAX_CONN; j++) {
        if ((names[j][0] != 0) && (strcmp(names[j], names[i]) != 0)) {
            len = strlen(names[j]);
            names[j][len] = '\n';
            names[j][len+1] = '\0';
            sendMsg(fd, names[j], NAME_LEN);
            names[j][len] = '\0';
        }
    }
}
//
void sendAll(int i, char msgOut[], pollfd *fds, int fdsInd)
{
    pollfd *author = &fds[i];

    for (int j = 0; j < fdsInd; j++) {
        if (fds[j].fd == author->fd)  
            continue;
        if  (fds[j].fd == mySock)    
            continue;
        sendMsg(fds[j].fd, msgOut, MSG_LEN);
    }
}
//
void sendErr(char *msg)
{
    perror(msg);
    exit(1);
}
//
void sendMsg(int fd, char msg[], int len)
{
    int sent = 0;

    if ((len == MSG_LEN) && (msg[len-1]!= '\0'))
        msg[len-1] = '\0';
    if ((len == MSG_LEN) && (msg[len-2]!= '\n'))
        msg[len-2] = '\n';

    while (sent < len) {
        sent = send(fd, msg, len, 0);
        if (sent == -1)
            sendErr("Sending message failed");
        else if (sent == len)
            return;
    }
}
//
void startHost(char myIP[])
{
    struct addrinfo hints, *servinfo;
    int yes = 1; 
    char port[] = "39071";

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;     // any IPv*
    hints.ai_socktype = SOCK_STREAM;

    if (getaddrinfo(myIP, port, &hints, &servinfo) != 0)
        sendErr("Getaddinfo() failed");

    if ((mySock = socket(servinfo->ai_family, 
                  servinfo->ai_socktype, servinfo->ai_protocol)) == -1)
        sendErr("Socket() failed");

    if (-1 == setsockopt(
              mySock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)))
        sendErr("setsockopt() failed");

    if (bind(mySock, servinfo->ai_addr, servinfo->ai_addrlen) == -1)
        sendErr("Bind() failed");

    if (listen(mySock, MAX_CONN) == -1)
        sendErr("listen() failed");

    if (debug) {
        printf("Host socket is %d\n", mySock);
        printf("Listening to port %s...\n", port);
    }
}

Client Code

#include <arpa/inet.h>
#include <ifaddrs.h>
#include <netdb.h>       //adds symbolic network constants
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define FDS_NUM            2
#define HOST_SIZE          4
#define MSG_LEN            255
#define MAX_CONN          11

enum { ERROR = -1, OFF = 0, SERV_DOWN = 0 , FAIL = 0, SUCCESS = 1 };

int debug;            //command-line argument
int mySock;           //received in prepareNet() and kept till the end

//int catchSignal(int sig, void (*handler)(int));
void chat();
//void doNoth(int sig) { sig = sig; return; }
void exit_closedConn();
int findHost(struct addrinfo *servinfo[]);
void handleArgs(int argc, char *argv[]);
void prepareNet(struct addrinfo *servinfo[]);
void sendErr(char *msg);

int main(int argc, char *argv[])
{
    struct addrinfo *servinfo[MAX_CONN];

    handleArgs(argc, argv);
    prepareNet(servinfo);
    //if (catchSignal(SIGALRM, doNoth) == -1)
    //        sendErr("Sigaction failed");
    if (!findHost(servinfo))
        sendErr("No hosts found");
    chat();

    return 0;
}
//
int catchSignal(int sig, void (*handler)(int))
{
    struct sigaction new;

    new.sa_handler = handler;
    sigemptyset(&new.sa_mask);
    new.sa_flags = 0;

    return sigaction(sig, &new, NULL);
}
//
void chat()
{
    struct pollfd pds[FDS_NUM];  
    int status;
    char msgIn[MSG_LEN];
    char usrMsg[MSG_LEN];
    pds[0].fd = 0;  //stdin
    pds[1].fd = mySock;
    pds[0].events = pds[1].events = POLLIN;
    while (1) {
        if (poll(pds, FDS_NUM, -1) == -1)
            sendErr("Poll failed");

        if (pds[0].revents & POLLIN) {
            fgets(usrMsg, MSG_LEN, stdin);
            if (send(pds[1].fd, usrMsg, MSG_LEN, 0) == -1)
                sendErr("Sent failed");
        } else if (pds[1].revents & POLLIN) {
            if ((status = recv(pds[1].fd, msgIn, MSG_LEN, 0)) == ERROR)
                sendErr("recv failed");
            else if (status == SERV_DOWN)
                exit_closedConn();
            printf("%s", msgIn);
            fflush(stdout);
        }
    }
}
//
void handleArgs(int argc, char *argv[])
{
    if (argc > 2) 
        sendErr("1 argument max");
    if ((argc == 2) && (strcmp("-d", argv[argc-1]) != 0)) 
        sendErr("input -d for debugging");
    else if (argc == 2)
        debug = 1;
}
//
void exit_closedConn()
{
    puts("Server closed connection. Exiting...");
    exit(1);
}
//
int findHost(struct addrinfo *servinfo[])
{
    puts("Searching for a server...");
    for (int i = 1; i < MAX_CONN; i++)   {
        if (debug)
            printf("Trying for 192.168.1.%d...\n", i);
        //alarm(1);
        if (connect(mySock, servinfo[i]->ai_addr, 
                    servinfo[i]->ai_addrlen) != -1)  {
            alarm(OFF);
            printf("Connected to 192.168.1.%d\n",i);
            return SUCCESS;
        }
    }
    return FAIL;
}
//
void prepareNet(struct addrinfo *servinfo[])
{
    struct addrinfo hints[MAX_CONN];
    char port[] = "39071";

    for (int i = 0; i < MAX_CONN; i++) {
        char host[HOST_SIZE];
        char ip[INET_ADDRSTRLEN] = "192.168.1.";

        memset(&hints[i], 0, sizeof(hints[i]));
        hints[i].ai_family = AF_UNSPEC;     // any IPv*
        hints[i].ai_socktype = SOCK_STREAM;
        sprintf(host, "%d", i);
        host[3] = '\0';
        strncat(ip, host, HOST_SIZE-1);

        if (getaddrinfo(ip, port, &hints[i], &servinfo[i]) != 0)
            sendErr("Getaddinfo() failed");
    }
    if ((mySock = socket(servinfo[0]->ai_family, 
            servinfo[0]->ai_socktype, servinfo[0]->ai_protocol)) == -1)
        sendErr("Socket() failed");
    if (debug)
        printf("Trying port %s using socket %d\n", port, mySock);
}
//
void sendErr(char *msg)
{
    perror(msg);
    exit(1);
}

UPDATE:

  1. Following Cix's and bruno's advices I was able to solve the first problem. Here are the details:
    • program creates a socket and tries to connect
    • after a second alarm is set
    • alarm()'s signal handler is a dummy function
    • if no connection is made program closes the socket

The question is how good is this approach?

int findHost(struct addrinfo *servinfo[])
{
    puts("Searching for a server...");
    for (int i = 1; i < MAX_CONN; i++)   {
        if ((mySock = socket(servinfo[0]->ai_family, 
                servinfo[0]->ai_socktype, servinfo[0]->ai_protocol)) == -1)
            sendErr("Socket() failed");
        if (debug) 
            printf("Trying for 192.168.1.%d...\n", i);
        alarm(1);
        if (connect(mySock, servinfo[i]->ai_addr, 
                    servinfo[i]->ai_addrlen) != -1)  {
            alarm(OFF);
            printf("Connected to 192.168.1.%d\n",i);
            //remove non-blocking
            return SUCCESS;
        }
        //sleep(1);
        close(mySock);
    }
    return FAIL;
}

Solution

  • Here a first version when the connections are tried one by one, using a non blocking socket and a select with a timeout of 1 second. I also changed few other things in the client to receive in argument :

    Full program of the client including not modified parts

    #include <arpa/inet.h>
    #include <ifaddrs.h>
    #include <netdb.h>       //adds symbolic network constants
    #include <poll.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    
    #define FDS_NUM            2
    #define HOST_SIZE          4
    #define MSG_LEN            255
    
    #define PORT 39071
    
    enum { ERROR = -1, OFF = 0, SERV_DOWN = 0 , FAIL = 0, SUCCESS = 1 };
    
    int Debug;       //command-line argument
    int MySock;      //the successfuly connected socket
    
    //int catchSignal(int sig, void (*handler)(int));
    void chat();
    //void doNoth(int sig) { sig = sig; return; }
    void exit_closedConn();
    int findHost(int maxhost);
    void handleArgs(int argc, char *argv[], int * maxhost);
    void sendErr(char *msg);
    
    int main(int argc, char *argv[])
    {
      int maxhost;  //search 192.168.1.1 .. 192.168.1.<MaxIP>
    
      handleArgs(argc, argv, &maxhost);
    
        //if (catchSignal(SIGALRM, doNoth) == -1)
        //        sendErr("Sigaction failed");
      if (!findHost(maxhost)) {
        puts("No hosts found");
        exit(-1);
      }
      else
        puts("host found");
    
      chat();
    
      return 0;
    }
    //
    int catchSignal(int sig, void (*handler)(int))
    {
        struct sigaction new;
    
        new.sa_handler = handler;
        sigemptyset(&new.sa_mask);
        new.sa_flags = 0;
    
        return sigaction(sig, &new, NULL);
    }
    //
    void chat()
    {
        struct pollfd pds[FDS_NUM];  
        int status;
        char msgIn[MSG_LEN];
        char usrMsg[MSG_LEN];
        pds[0].fd = 0;  //stdin
        pds[1].fd = MySock;
        pds[0].events = pds[1].events = POLLIN;
        while (1) {
            if (poll(pds, FDS_NUM, -1) == -1)
                sendErr("Poll failed");
    
            if (pds[0].revents & POLLIN) {
                fgets(usrMsg, MSG_LEN, stdin);
                if (send(pds[1].fd, usrMsg, MSG_LEN, 0) == -1)
                    sendErr("Sent failed");
            } else if (pds[1].revents & POLLIN) {
                if ((status = recv(pds[1].fd, msgIn, MSG_LEN, 0)) == ERROR)
                    sendErr("recv failed");
                else if (status == SERV_DOWN)
                    exit_closedConn();
                printf("%s", msgIn);
                fflush(stdout);
            }
        }
    }
    
    //
    
    void handleArgs(int argc, char *argv[], int * maxhost)
    {
      if ((argc < 2) || 
          (argc > 3) ||
          (sscanf(argv[1], "%d", maxhost) != 1) ||
          (*maxhost < 1) ||
          ((Debug = (argc == 3)) && strcmp(argv[2], "-d"))) {
        fprintf(stderr, "Usage: %s max_host [-d]\n", *argv);
        exit(-1);
      }
    }
    
    //
    
    void exit_closedConn()
    {
      puts("Server closed connection. Exiting...");
      exit(1);
    }
    
    //
    
    int do_connect(int host, fd_set * fdset)
    {
      if (Debug)
        printf("Trying for 192.168.1.%d...\n", host);
    
      int sock = socket(AF_INET, SOCK_STREAM, 0);
    
      if (fcntl(sock, F_SETFL,O_NONBLOCK) != 0)
        sendErr("fcntl nonblock");
    
      struct sockaddr_in sin = { 0 };
    
      sin.sin_addr.s_addr = htonl(0xC0a80100 + host); /* 192.168.1.host */
      sin.sin_port = htons(PORT);
      sin.sin_family = AF_INET;
    
      errno = 0;
    
      int r = connect(sock, (struct sockaddr*) &sin, sizeof(sin));
    
      if ((r < 0) && (errno != EINPROGRESS)) {
        if (Debug)
          printf("cannot connect to 192.168.1.%d\n", host);
        close(sock);
        return 0;
      }
    
      FD_SET(sock, fdset);
      return sock;
    }
    
    int findHost(int maxhost)
    {
      int host;
    
      puts("Searching for a server...");
    
      for (host = 1; host <= maxhost; host += 1) {
        fd_set rset;
    
        FD_ZERO(&rset);
        if ((MySock = do_connect(host, &rset)) != 0) {
          fd_set wset = rset;
          struct timeval timeout;
          int r;
    
          timeout.tv_sec = 2;
          timeout.tv_usec = 0;
    
          r = select(MySock+1, &rset, &wset, NULL, &timeout);
          if (r < 0)
            sendErr("select");
          else if (r) {
            socklen_t len = sizeof(r);
    
            if (!getsockopt(MySock, SOL_SOCKET, SO_ERROR, &r, &len) && !r) {
              int flags;
    
              if (Debug)
                printf("connected to 192.168.1.%d\n", host);
    
              /* put socket in blocking mode */
              flags = fcntl(MySock, F_GETFL, 0);
    
              if (fcntl(MySock, F_SETFL, flags ^ O_NONBLOCK) < 0)
                sendErr("fcntl set non blocking");
    
              alarm(OFF);
              return SUCCESS;
            }
          }
          if (Debug)
            printf("cannot connect to 192.168.1.%d\n", host);
          close(MySock);
        }
      }
    
      return FAIL;
    }
    
    //
    void sendErr(char *msg)
    {
        perror(msg);
        exit(1);
    }
    

    However if the max host number is high even limiting to 1 second per host that can make a too long time.

    Here a second proposal reducing the needed time doing the connect attempts for several addresses rather than only one, still using non blocking sockets and a select with a timeout of 1 sec.

    The client is also modified to receive in argument :

    Full program of the client including not modified parts :

    #include <arpa/inet.h>
    #include <ifaddrs.h>
    #include <netdb.h>       //adds symbolic network constants
    #include <poll.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    
    #define FDS_NUM            2
    #define HOST_SIZE          4
    #define MSG_LEN            255
    
    #define PORT 39071
    
    enum { ERROR = -1, OFF = 0, SERV_DOWN = 0 , FAIL = 0, SUCCESS = 1 };
    
    int Debug;       //command-line argument
    int MySock;      //the successfuly connected socket
    
    //int catchSignal(int sig, void (*handler)(int));
    void chat();
    //void doNoth(int sig) { sig = sig; return; }
    void exit_closedConn();
    int findHost(int maxhost, int npar);
    void handleArgs(int argc, char *argv[], int * maxhost, int * npar);
    void sendErr(char *msg);
    
    int main(int argc, char *argv[])
    {
      int maxhost;   //search 192.168.1.1 .. 192.168.1.<MaxIP>
      int npar = 10; //number of // connections
    
      handleArgs(argc, argv, &maxhost, &npar);
    
        //if (catchSignal(SIGALRM, doNoth) == -1)
        //        sendErr("Sigaction failed");
      if (!findHost(maxhost, npar))
        sendErr("No hosts found");
      else
        puts("host found");
    
      chat();
    
      return 0;
    }
    //
    int catchSignal(int sig, void (*handler)(int))
    {
        struct sigaction new;
    
        new.sa_handler = handler;
        sigemptyset(&new.sa_mask);
        new.sa_flags = 0;
    
        return sigaction(sig, &new, NULL);
    }
    //
    void chat()
    {
        struct pollfd pds[FDS_NUM];  
        int status;
        char msgIn[MSG_LEN];
        char usrMsg[MSG_LEN];
        pds[0].fd = 0;  //stdin
        pds[1].fd = MySock;
        pds[0].events = pds[1].events = POLLIN;
        while (1) {
            if (poll(pds, FDS_NUM, -1) == -1)
                sendErr("Poll failed");
    
            if (pds[0].revents & POLLIN) {
                fgets(usrMsg, MSG_LEN, stdin);
                if (send(pds[1].fd, usrMsg, MSG_LEN, 0) == -1)
                    sendErr("Sent failed");
            } else if (pds[1].revents & POLLIN) {
                if ((status = recv(pds[1].fd, msgIn, MSG_LEN, 0)) == ERROR)
                    sendErr("recv failed");
                else if (status == SERV_DOWN)
                    exit_closedConn();
                printf("%s", msgIn);
                fflush(stdout);
            }
        }
    }
    
    //
    
    void handleArgs(int argc, char *argv[], int * maxhost, int * npar)
    {
      if ((argc < 2) || 
          (argc > 4) ||
          (sscanf(argv[1], "%d", maxhost) != 1) ||
          (*maxhost < 1) ||
          ((argc >= 3) && ((sscanf(argv[2], "%d", npar) != 1) || (*npar < 1))) ||
          ((Debug = (argc == 4)) && strcmp(argv[3], "-d"))) {
        fprintf(stderr, "Usage: %s max_host [n_par [-d]] (default n_par is 10)\n", *argv);
        exit(-1);
      }
    }
    
    //
    
    void exit_closedConn()
    {
      puts("Server closed connection. Exiting...");
      exit(1);
    }
    
    //
    
    int do_connect(int host, int * highersock, fd_set * fdset)
    {
      if (Debug)
        printf("Trying for 192.168.1.%d...\n", host);
    
      int sock = socket(AF_INET, SOCK_STREAM, 0);
    
      if (fcntl(sock, F_SETFL,O_NONBLOCK) != 0)
        sendErr("fcntl nonblock");
    
      struct sockaddr_in sin = { 0 };
    
      sin.sin_addr.s_addr = htonl(0xC0a80100 + host); /* 192.168.1. */
      sin.sin_port = htons(PORT);
      sin.sin_family = AF_INET; /////AF_UNSPEC;     // any IPv*
    
      errno = 0;
    
      int r = connect(sock, (struct sockaddr*) &sin, sizeof(sin));
    
      if ((r < 0) && (errno != EINPROGRESS)) {
        close(sock);
        if (Debug)
          printf("cannot connect to 192.168.1.%d\n", host);
        return 0;
      }
    
      if (sock > *highersock)
        *highersock = sock;
    
      FD_SET(sock, fdset);
      return sock;
    }
    
    int findHost(int maxhost, int npar)
    {
      int host = 1;
    
      puts("Searching for a server...");
    
      while (host <= maxhost) {
        fd_set rset;
        int highersock = 0;
        int i = 0, nsocks = 0;
        int socks[npar];    /* socks under connection or 0 */
        int hosts[npar];    /* the next host to check */
    
        FD_ZERO(&rset);
    
        /* establish socket list */
        do {
          int sock;
    
          if ((sock = do_connect(host, &highersock, &rset)) != 0) {
            socks[i] = sock;
            hosts[i++] = host;
            nsocks += 1;
          }
          host += 1;
        }  while ((i != npar) && (host <= maxhost));
    
        /* check connects */
        while (nsocks)  {
          fd_set rset2 = rset, wset2 = rset;
          struct timeval timeout;
          int r, j;
    
          timeout.tv_sec = 1;
          timeout.tv_usec = 0;
          r = select(highersock+1, &rset2, &wset2, NULL, &timeout);
    
          if (r < 0)
            sendErr("select");
    
          if (r == 0) {
            /* timeout, close all */
            for (j = 0; j != i; ++j) {
              if (socks[j])
                close(socks[j]);
            }
            break;
          }
    
          for (j = 0; j != i; ++j) {
            int sock = socks[j];
    
            if (FD_ISSET(sock, &rset2) || FD_ISSET(sock, &wset2)) {
              socklen_t len = sizeof(r);
    
              socks[j] = 0;
              FD_CLR(sock, &rset);
              nsocks -= 1;
    
              if ((getsockopt(sock, SOL_SOCKET, SO_ERROR, &r, &len) < 0) || r) {
                if (Debug)
                  printf("cannot connect to 192.168.1.%d\n", hosts[j]);
                close(sock);
              }
              else {
                if (Debug)
                  printf("connected to 192.168.1.%d\n", hosts[j]);
    
                /* close other sockets */
                for (j = 0; j != i; ++j) {
                  if (socks[j] && (socks[j] != sock))
                    close(socks[j]);
                }
    
                MySock = sock;
    
                /* put socket in blocking mode */
                int flags = fcntl(MySock, F_GETFL, 0);
    
                if (fcntl(MySock, F_SETFL, flags ^ O_NONBLOCK) < 0)
                  sendErr("fcntl set non blocking");
    
                alarm(OFF);
                return SUCCESS;
              }
            }
          }
        }
      }
    
      return FAIL;
    }
    
    //
    void sendErr(char *msg)
    {
        perror(msg);
        exit(1);
    }
    

    The other part of your program are unchanged, note in chat you send a fixed size array so potentially including non initialized bytes.