C socket programming: select() is returning 0 despite messages sent from server

Posted by Fantastic Fourier on Stack Overflow See other posts from Stack Overflow or by Fantastic Fourier
Published on 2010-05-23T23:48:26Z Indexed on 2010/05/23 23:50 UTC
Read the original article Hit count: 223

Filed under:
|
|
|

Hey all, I'm using select() to recv() messages from server, using TCP/IP. When I send() messages from the server, it returns a reasonable number of bytes, saying it's sent successful. And it does get to the client successfully when I use while loop to just recv(). Everything is fine and dandy.

while(1)
   recv() // obviously pseudocode

However, when I try to use select(), select() returns 0 from timeout (which is set to 1 second) and for the life of me I cannot figure out why it doesn't see the messages sent from the server. I should also mention that when the server disconnects, select() doesn't see that either, where as if I were to use recv(), it would return 0 to indicate that the connection using the socket has been closed. Any inputs or thoughts are deeply appreciated.

#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>


#define SERVER_PORT 10000
#define MAX_CONNECTION  20
#define MAX_MSG     50


struct client
{
    char c_name[MAX_MSG];
    char g_name[MAX_MSG];

int csock;
int host;   // 0 = not host of a multicast group    

struct sockaddr_in client_address;

struct client * next_host;
struct client * next_client;    

};

struct fd_info { char c_name[MAX_MSG];

int socks_inuse[MAX_CONNECTION];
int sock_fd, max_fd;
int exit;

struct client * c_sys;
struct sockaddr_in c_address[MAX_CONNECTION];

struct sockaddr_in server_address;
struct sockaddr_in client_address;

fd_set read_set;

};

struct message { char c_name[MAX_MSG]; char g_name[MAX_MSG]; char _command[3][MAX_MSG]; char _payload[MAX_MSG];

struct sockaddr_in client_address;
struct client peer;

};

int main(int argc, char * argv[]) { char * host; char * temp;

int i, sockfd;
int msg_len, rv, ready;
int connection, management, socketread;
int sockfds[MAX_CONNECTION];


// for three threads that handle new connections, user inputs and select() for sockets
pthread_t connection_handler, manager, socket_reader;

struct sockaddr_in server_address, client_address;
struct hostent * hserver, cserver;
struct timeval timeout;
struct message msg;
struct fd_info info;
info.exit = 0;  // exit information: if exit = 1, threads quit
info.c_sys = NULL;

// looking up from the host database
if (argc == 3)
{
    host = argv[1];         // server address
    strncpy(info.c_name, argv[2], strlen(argv[2]));     // client name
}
else
{
    printf("plz read the manual, kthxbai\n");
    exit(1);
}

printf("host is %s and hp is %p\n", host, hserver);
hserver = gethostbyname(host);
if (hserver)
{
    printf("host found: %s\n", hserver->h_name );
}
else
{
    printf("host not found\n");
    exit(1);
}
// setting up address and port structure information on serverside
bzero((char * ) &server_address, sizeof(server_address)); // copy zeroes into string
server_address.sin_family = AF_INET;
memcpy(&server_address.sin_addr, hserver->h_addr, hserver->h_length);
server_address.sin_port = htons(SERVER_PORT);

bzero((char * ) &client_address, sizeof(client_address)); // copy zeroes into string
client_address.sin_family = AF_INET;
client_address.sin_addr.s_addr = htonl(INADDR_ANY);
client_address.sin_port = htons(SERVER_PORT);

// opening up socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
    exit(1);
else
{
    printf("socket is opened: %i \n", sockfd);
    info.sock_fd = sockfd;
}

// sets up time out option for the bound socket 
timeout.tv_sec = 1;     // seconds
timeout.tv_usec = 0; // micro seconds ( 0.5 seconds)
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval));

// binding socket to a port
rv = bind(sockfd, (struct sockaddr *) &client_address, sizeof(client_address));
if (rv < 0)
{
    printf("MAIN: ERROR bind() %i: %s\n", errno, strerror(errno));
    exit(1);
}
else
    printf("socket is bound\n");

printf("MAIN: %li \n", client_address.sin_addr.s_addr);


// connecting
rv = connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address));
info.server_address = server_address;
info.client_address = client_address;
info.sock_fd = sockfd;
info.max_fd = sockfd;
printf("rv = %i\n", rv);
if (rv < 0)
{
    printf("MAIN: ERROR connect() %i:  %s\n", errno, strerror(errno));
    exit(1);
}
else
    printf("connected\n");

fd_set readset;
FD_ZERO(&readset);
FD_ZERO(&info.read_set);
FD_SET(info.sock_fd, &info.read_set);

while(1)
{
    readset = info.read_set;
    printf("MAIN: %i \n", readset);
    ready = select((info.max_fd)+1, &readset, NULL, NULL, &timeout);

    if(ready == -1)
    {
        sleep(2);
        printf("TEST: MAIN: ready = -1. %s \n", strerror(errno));
    }
    else if (ready == 0)
    {
        sleep(2);
        printf("TEST: MAIN: ready = 0. %s \n", strerror(errno));
    }
    else if (ready > 0)
    {
        printf("TEST: MAIN: ready = %i. %s at socket %i \n", ready, strerror(errno), i);
        for(i = 0; i < ((info.max_fd)+1); i++)
        {
            if(FD_ISSET(i, &readset))
            {
                rv = recv(sockfd, &msg, 500, 0);
                if(rv < 0)
                    continue;
                else if(rv > 0)
                    printf("MAIN: TEST: %s %s \n", msg._command[0], msg._payload);
                else if (rv == 0)
                {
                    sleep(3);
                    printf("MAIN: TEST: SOCKET CLOSEDDDDDD \n");
                }

                FD_CLR(i, &readset);
            }
        }

    }
    info.read_set = readset;        

}

// close connection
close(sockfd);
printf("socket closed. BYE! \n");
return(0);

}

© Stack Overflow or respective owner

Related posts about c

    Related posts about sockets