This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: strange select() and recvfrom() behaviour


Hi,

actually you were right, I was a bit too quick with my extract. It didn't
contain an important line. I'm also sending out stuff through that socket.
So here it goes, you can copy paste and compile this.

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

#define MYPORT 8080    		// The default port the server will listen on.
#define MAXBUFLEN 70

int main(int argc, char *argv[])
{
    int sockfd;
    int port = MYPORT;
    struct sockaddr_in my_addr;    // my address information
    struct sockaddr_in their_addr; // connector's address information
    int bytes_received;
    char buffer[MAXBUFLEN];
    struct timeval tv;
    fd_set rfds;
    int retval;

    socklen_t addr_len = sizeof(their_addr);

    // open the UDP socket and bind it
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(port);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    memset(my_addr.sin_zero, '\0', sizeof(my_addr.sin_zero));

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        perror("Could not open socket");
        exit(1);
    }

    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof (my_addr)) == -1)
    {
        perror("Could not bind socket.");
        exit(1);
    }

    printf("Server is ready and listening on port %d\n",
ntohs(my_addr.sin_port));

    while (1)
    {
        tv.tv_sec = 0;
        tv.tv_usec = 0.01*1000000;

        FD_ZERO(&rfds);
        FD_SET(sockfd, &rfds);
        retval = select(sockfd+1, &rfds, NULL, NULL, &tv);

        if (retval > 0)
        {
            // We received data from the socket.

            bytes_received = recvfrom(sockfd, buffer, MAXBUFLEN , 0,
(struct sockaddr *)&their_addr, &addr_len);

            printf("retval:%d\t%d bytes received.\n", retval,
bytes_received);
        }
        else
        {
            // select() timed out

            sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr
*)&their_addr, sizeof their_addr);
        }
    }

    // can't be reached, the OS will take care of it anyways, but oh well...
    close(sockfd);

    return 0;
}


Now if you compile it in cygwin and let it run on a windows machine and
send it a UDP packet you will see that select() keeps returning with 1
even though the socket has no data to read. Do the same on linux and it
works like it should, select() returns 1 only if there is actually
incoming data to read.

Marcell



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]