Socket client using Select

13,775

The fd_set must be initialized before each use.

Your code should be like:

int clientSelect(char **ipAddr ,int port , int count)
{
    SOCKET max_sd = 0;
    SOCKET socketId[10] = {0};
    SOCKET sd = 0 ;

    fd_set readfds;
    int i ,j , ret;
    char recvBuf[1024] = "";
    char errMsg[256] = "" ;
    struct sockaddr_in server ;

    // Socket Initialization
    for(i = 0; i<count ; i++)
    {
        ret = initSocket(&socketId[i]);//Small function to create socket
        if (ret != 1)
        {
            return ret ;
        }
        //Server info
        server.sin_addr.s_addr  = inet_addr(ipAddr[i]);
        server.sin_family       = AF_INET;
        server.sin_port         = htons(port);
        // Conect to server
        if (connect(socketId[i], (struct sockaddr *)&server , sizeof(server)) < 0)
        {
            printf("connect ::Failed to connect to server %s:%d",ipAddr[i],port);
            return -1;
        }       
    }


    while(TRUE)
    {
        // init fd_set
        FD_ZERO(&readfds); // added by siva to initialize socket descriptors
        for(i = 0; i<count ; i++)
        {
            //FD_ZERO(&readfds); // Commented by siva to avoid initialization for each socket
            FD_SET(socketId[i], &readfds); 
            max_sd = (max_sd>socketId[i])?max_sd:socketId[i];
        }
        ret = select(max_sd + 1, &readfds, NULL, NULL, NULL);
        if (ret < 0)
        {
            printf("select failed\n ");
            return -1;
        }
        // warning: you don't know the max_sd value
        for(i = 0; i<count ; i++)
        {
            sd = socketId[i] ;
            if (FD_ISSET(sd, &readfds)) 
            {
                ret = recv(sd,(char *)recvBuf,sizeof(recvBuf), 0);
                if(ret > 0 )
                {
                    printf("Message received from socket %d : %s\n",sd,recvBuf);
                    send(sd,(char *)recvBuf,strlen(recvBuf),0);
                }
            }
        }
    }

    return ret ;

}
Share:
13,775
Admin
Author by

Admin

Updated on June 23, 2022

Comments

  • Admin
    Admin almost 2 years

    Im trying to implement a client function which can establish connection with multiple servers using select() function. But I'm not a expert in using select() function. However my client can enable a connection with the multiple servers but it could not able to read messages from those multiple servers.

    As per my following example , i connected my client with two servers ( 192.168.100.136, 192.168.100.138). After connected with those two servers , my client was receiving messages from only one server (192.168.100.136) , instead of receiving messages from multiple servers..

    I'm not sure about the way I used select() function in my sample program. Please correct my sample application to get the desired o/p.. Thanks in advance

    int main()
    {
        int port = 10001 ;
        char ip[][32] = {"192.168.100.136","192.168.100.138"};
        int count = 2 ;
        int ret = clientSelect(ip,port,count);
        return 0 ;
    }   
    int clientSelect(char **ipAddr ,int port , int count)
        {
        SOCKET max_sd = 0;
        SOCKET socketId[10] = {0};
        SOCKET sd = 0 ;
        SOCKET client_sock[1024] = {0} ;
        fd_set readfds;
        int i ,j , ret;
        char recvBuf[1024] = "";
        char errMsg[256] = "" ;
        struct sockaddr_in server ;
    
        FD_ZERO(&readfds);
        // Socket Initialization
        for(i = 0; i<count ; i++)
        {
            ret = initSocket(&socketId[i]);//Small function to create socket
            if (ret != 1)
            {
                return ret ;
            }
            //Server info
            server.sin_addr.s_addr  = inet_addr(ipAddr[i]);
            server.sin_family       = AF_INET;
            server.sin_port         = htons(port);
            // Conect to server
            if (connect(socketId[i], (struct sockaddr *)&server , sizeof(server)) < 0)
            {
                printf("connect ::Failed to connect to server %s:%d",ipAddr[i],port);
                return -1;
            }
            // Set Socket fd
            FD_SET(socketId[i], &readfds); 
    
            max_sd = (max_sd>socketId[i])?max_sd:socketId[i];
        }
        while(TRUE)
        {
            ret = select(max_sd + 1, &readfds, NULL, NULL, NULL);
            if (ret < 0)
            {
                printf("select failed\n ");
                return -1;
            }
            for ( j = 0 ; j<max_sd ; j++)
            {
                sd = client_sock[j] ;
                if (FD_ISSET(sd, &readfds)) 
                {
                    ret = recv(sd,(char *)recvBuf,sizeof(recvBuf), 0);
                    if(ret > 0 )
                    {
                        printf("Message received from socket %d : %s\n",sd,recvBuf);
                        send(sd,(char *)recvBuf,strlen(recvBuf),0);
                    }
                }
            }
        }
    
        return ret ;
    
    }
    
  • Admin
    Admin over 7 years
    Hi , I changed my function as per your suggestion... But still I'm getting messages from only one server rather than receiving messages from both server.... Please guide me further to get the expected o/p.. Actually my requirement is to implement a client function to establish a connection with multiple servers & to monitor the message transaction using select() concept... please correct me , whether i'm going in a right way in my sample function to satisfy the requirement or not... @purplepsycho
  • Admin
    Admin over 7 years
    Hi @purplepsycho , I did one small correction in your answer to get the things are working properly as expected... Please correct me , If I did anything wrong in the modification. Thank u