Member Avatar for hohoho89

Hi, I was wondering how to make client connect to multiple servers.
I decided to use select for this but I don't see how it should work well like in the server.

Pseudocode:

void connect_to_server(char argv[]) {


    if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == ERROR) {
        perror("socket problem: ");
        exit(1);
    }
    if ((hostp = gethostbyname(argv)) == 0) {

    } else {


        memset(&serveraddr, 0, sizeof (serveraddr));
        serveraddr.sin_family = AF_INET;

        memcpy(&serveraddr.sin_addr, hostp->h_addr, hostp->h_length);
        serveraddr.sin_port = htons(portnumber);
        if (bind(sock, (struct sockaddr *) & clientaddr, sizeof (clientaddr)) == ERROR) {;
        }


                process();


}
}

/**
 * process we want to connect to server in tcp and udp selective function to
 * get warnings from the server and statistics
 * in tcp. This makes it easier for us to clean up wether the server has shutdown
 * or not.
 *
 * @globl sock the given socket when connected
 * @globl new the udp socketconnection
 */

void *process() {
    fd_set read_set;
    struct sockaddr_in udpserveraddr;
    socklen_t addrlen, addrlen2;
    int selective,i,fdmax = 0;
    char data[SENDBUFFER];

    /*UDP creation format*/

    new = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    memset(&udpserveraddr, 0, sizeof (udpserveraddr));
    udpserveraddr.sin_family = AF_INET;
    memcpy(&udpserveraddr.sin_addr.s_addr, hostp->h_addr, hostp->h_length);
    udpserveraddr.sin_port = htons(portnumber);
    udpserveraddr.sin_addr.s_addr = INADDR_ANY;

    if (bind(new, (struct sockaddr *) & udpserveraddr, sizeof (udpserveraddr)) == ERROR) {

    }


    while (1) {

        FD_ZERO(&read_set);
        FD_SET(sock, &read_set);
        FD_SET(new, &read_set);
        FD_SET(fileno(stdin), &read_set);
        fdmax = sock+1;
        selective = select(FD_SETSIZE, &read_set, NULL, NULL, NULL);

        switch (selective) {

            default:


                if (FD_ISSET(fileno(stdin), &read_set)) {/*user input data on keyboard*/
                    small_shell();
                    fflush(stdout);

                }
                for(i = 0; i<=fdmax;i++) {
                if (FD_ISSET(i, &read_set)) { /*We have received something from the server*/
                    if(i == sock) {
                            if (connect(i, (struct sockaddr *) & serveraddr, sizeof (serveraddr)) == ERROR) {
        check_connection();

        }


        /*Making two processes where each would be a tcp and udp handling*/
        if (insert_tolist(&firstlist,i, machine, clientaddr) == 0) {
printf("inserted to a list\n");
        } else {
            flagstop = 0;
            send_intro(i); /*SEND MONITOR THRESHOLD AND DURATION TO SERVER FIRST*/

//pthread_create(&server_connection,NULL,&process,NULL);

        }

                    }else {
//Receive TCP messages

                    }

                }
                }
                }
                if (FD_ISSET(new, &read_set)) {
//Receive UDP packets
               }

                break;

        }

    }



}

Get/Read Comer and Stevens "Internetworking with TCP/IP, Volume 3, Client-Server Programming". From what I am reading, you are just guessing what to do. On the client side, you open socket, bind it to the server address, connect to the server, then loop into send-message/get-reply. You can use select() on the client side, usually to wait for the socket to be able to send more data, or wait for the reply to come back from the server, or determine that there was an exception/error. If you are communicating with multiple servers, then using select() to wait for one of them to reply before reading the message is appropriate. In any case, you connect() after you select() and that is just wrong. You should only connect once to each server, then send your messages and use select (usually with a timer) to be informed when data is available to read.

One side note: if you use a thread for each connection, then you can send-message/get-reply without using select unless the socket buffer is full, in which case select() can tell you when the socket is available to take more data, or you can just use blocking send() and read() calls.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.