Siva Siva - 2 months ago 10
C Question

Socket client using Select

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 ;

}

Answer

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
        for(i = 0; i<count ; i++)
        {
            FD_ZERO(&readfds);
            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);
                }
                Sleep(10);
            }
        }
    }

    return ret ;

}
Comments