Select and UDP problems

From: Kevin Pearson (pearson@boi.hp.com)
Date: Wed Jan 19 2000 - 12:22:31 EST


Hello,

I have a question reguarding select on a UDP socket. The following
program creates a UDP socket, sends a character, does a select for five
seconds waiting for a response, and recieves a response, if there was one.

This works fine when there is a service that responds to the request, but
if there isn't, select still returns immediatly and with readSet
set. Then recvfrom return -1 with an errno of 111 (ECONNREFUSED).

On HP-UX 10.20 and Solaris 5.7, when there is no response, select waits
for 5 seconds and times out.

I'm using Linux 2.2.12 SMP, glibc-2.1.2.

I've tried searching the linux-kernel archives, but could find nothing.

Am I doing something wrong here or is this a defect in select?
Please reply to kevin_pearson@hp.com as I'm not subscribed to the list.

Thanks in advance,
Kevin Pearson
kevin_pearson@hp.com

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

int main(int argc, char **argv)
{
        int fd = -1;
        int dest_port = -1;
        int ret = -1;
        struct sockaddr_in myaddr;
        int addr_size = sizeof(myaddr);
  struct hostent *hostname = NULL;
        fd_set readSet;
        fd_set errSet;
        struct timeval timeout;
        char buf[512];

        if (argc < 3)
        {
                printf("\nUsage: test hostname port\n\n");
                exit(-1);
        }
        
  hostname = gethostbyname(argv[1]);
  dest_port = atoi(argv[2]);

  if (hostname == NULL)
        {
                printf("Could not resolv hostname\n");
                exit(-1);
        }
        
  fd = socket(AF_INET, SOCK_DGRAM, 0);
        if (fd < 0)
        {
                printf("Could not open socket\n");
        }

        addr_size = sizeof(myaddr);
        memset(&myaddr, 0, addr_size);

        myaddr.sin_family = AF_INET;
        myaddr.sin_port = htons(dest_port);
        memcpy(&myaddr.sin_addr, hostname->h_addr_list[0], hostname->h_length);

        ret = sendto(fd, "*", 1, 0, &myaddr, sizeof(myaddr));
        if (ret < 0)
                printf("send returned ret=%d, errno=%d\n", ret, errno);
        
        FD_ZERO(&readSet);
        FD_SET(fd, &readSet);

        FD_ZERO(&errSet);
        FD_SET(fd, &errSet);

        timeout.tv_sec = 5;
        timeout.tv_usec = 0;

        ret = select(fd + 1, &readSet, NULL, &errSet, &timeout);
        if (ret < 0)
                printf("select returned ret=%d, errno=%d\n", ret, errno);
                
        if ( FD_ISSET(fd, &readSet) )
                printf("readSet fired\n");
        if ( FD_ISSET(fd, &errSet) )
                printf("errSet fired\n");

        if ( (ret > 0) && (FD_ISSET(fd, &readSet)) && (!FD_ISSET(fd, &errSet)) )
        {
                ret = recvfrom(fd, buf, sizeof(buf), 0, &myaddr, &addr_size);
                if (ret < 0)
                        printf("recvfrom returned ret=%d, errno=%d\n", ret, errno);
                else
                        printf("buff is %s\n", buf);
        }

        close(fd);
        return 0;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Jan 23 2000 - 21:00:20 EST