Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using select to waiting for data on a client socket

Tags:

c

select

sockets

Any ideas why when the server writes a socket while the client is waiting on select, select never finishes?

I am using c to communicate between sockets. My client connects to my server fine.

socket_desc=socket(AF_INET,SOCK_STREAM,0);//create the socket descriptor
client->address.sin_addr.s_addr = inet_addr(ipAddress);
client->address.sin_family = AF_INET;
client->address.sin_port = htons(port);

bind(socket_desc,&address,sizeof(address));
connect(socket_desc, &address, sizeof(address));

When I use recv to block and listen for data, everything works fine:

int bytesRead = 1;
while(bytesRead){
    int bufsize=1024;        
    char *buffer=malloc(bufsize);
    bytesRead = recv(socket_desc, buffer, bufsize, 0);
    printf("CLIENT RECV: %s", buffer);
}

If I try to use select, it doesn't seem to read any data. If I add STDIN to the fd_set, I can force it to read from the socket, but select doesn't seem to get triggered from the socket_desc reading in data...?

int running = 1;
while(running){
    /* wait for something to happen on the socket */
    struct timeval selTimeout;
    selTimeout.tv_sec = 2;       /* timeout (secs.) */
    selTimeout.tv_usec = 0;            /* 0 microseconds */
    fd_set readSet;
    FD_ZERO(&readSet);
    FD_SET(STDIN_FILENO, &readSet);//stdin manually trigger reading
    FD_SET(socket_desc, &readSet);//tcp socket

    int numReady = select(3, &readSet, NULL, NULL, &selTimeout);
            //IT ONLY GETS PAST SELECT ON RETURN FROM THE KEYBOARD
    if(numReady > 0){
        char buffer[100] = {'\0'};
        int bytesRead = read(socket_desc, &buffer, sizeof(buffer));
        printf("bytesRead %i : %s", bytesRead, buffer);
        if(bytesRead == 0){
            running = FALSE;
            printf("Shutdowning client.\n");

        }
    }
like image 946
joels Avatar asked Jan 25 '11 02:01

joels


People also ask

What does select () do in socket?

The select function returns the total number of socket handles that are ready and contained in the fd_set structures, zero if the time limit expired, or SOCKET_ERROR if an error occurred. If the return value is SOCKET_ERROR, WSAGetLastError can be used to retrieve a specific error code.

How do you wait on a socket?

To wait for activity on any sockets managed by a TCP/IP application, use a SOCKET TYPE=SELECT command. To wait for activity on the sockets, any or all of read, write, and exception lists can be passed to the SOCKET TYPE=SELECT command.

Can you read and write from the same client socket?

Sockets are full duplex, so you can read while you write and vice-versa.


1 Answers

The first parameter to select should be the maximum socket id plus 1. So in your case, it should be

socket_desc+1

Can you try with that and see if it works?

The reason it only gets when you press a key on the keyboard is because stdin is 0, which would be within 0 - (3 - 1) range, which is what is checked. If you set the first parameter to socket_desc+1, then 0 - (socket_desc) range should be checked for ready sockets

like image 138
vmpstr Avatar answered Oct 30 '22 11:10

vmpstr