Date: Mon, 01 Aug 2011 17:09:37 +0200 From: "Christoph P.U. Kukulies" <kuku@kukulies.org> To: freebsd-questions@freebsd.org Subject: Re: invalid argument in select() when peer socket is in FD_SET Message-ID: <4E36C1B1.4090708@kukulies.org> In-Reply-To: <4E352563.2070808@kukulies.org> References: <4E352563.2070808@kukulies.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Am 31.07.2011 11:50, schrieb Christoph P.U. Kukulies: > I have written a small to test TCP/IP roundtrip times of the packets > in a proprietary protocol and while > compiling and running this server on different platforms (Windows > 7/cygwin, UbuntuLinux, FreeBSD 8.0 Release), I found > that the server produces an error when the listening socket (on which > the accpet() is performed) is member of the select() > fd_set. > > On the other platforms the program works without error, just under > FreeBSD I'm getting this "invalid argument" error. > > Comments appreciated (despite comments about the error checking logic :) > > Here is the code: > // testsrv.c > // gcc -o testsrv testsrv.c > // > > #include <stdio.h> > #include <unistd.h> > #include <sys/types.h> > #include <sys/socket.h> > #include <netinet/in.h> > #include <arpa/inet.h> > #include <netdb.h> > #include <string.h> > > #include <sys/select.h> > > #define USEDBUFSIZ 60 > #define MAX_HOSTNAME 256 > #define MAXFDS 256 > #define CLRBUF memset(buf,0,sizeof(buf)) > #define max(a,b) (((a) > (b)) ? (a) : (b)) > static unsigned char buf[256]; > int array_of_fds[MAXFDS]; > static fd_set clientfds; > #define SOCKET int > void *memset(void *, int, size_t); > int enter (int); > int remov (int); > int invalidip (char *); > void exit (int); > int getv (int, unsigned char *, int); > int getfds (); > > int > main(int argc, char **argv) > { > int nfds; > static fd_set readfds; > SOCKET ListenSocket, newsockfd; > struct sockaddr_in cli_addr; > struct sockaddr_in service; > struct hostent *thisHost; > int bOptVal = 0; > int bOptLen = sizeof(int); > char hostname[256]; > char *host_addr; > struct in_addr addr = {0}; > char *ip; > u_short port; > int iResult = 0; > int i , n, m, clilen, dummy, connect = 0; > struct timeval tv; > //--------------------------------------- > //Create a listening socket > ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); > if (ListenSocket == -1) { > perror("socket creation"); > return 1; > } else > printf("ListenSocket=%d\n", ListenSocket); > //--------------------------------------- > //Bind the socket to the local IP address > // and port 3210 > port = 3210; > if (gethostname(hostname, 256)) > perror("gethostname failed\n"), exit(3); > printf("%s\n", hostname), fflush(stdout); > thisHost = gethostbyname(hostname); > ip = inet_ntoa(*(struct in_addr *)(*thisHost->h_addr_list)); > > > if (argc == 2) { > host_addr = argv[1]; > service.sin_addr.s_addr = inet_addr(host_addr); > thisHost = gethostbyaddr((const char *)&service.sin_addr.s_addr, > sizeof(service.sin_addr.s_addr), > AF_INET); > if (thisHost == 0) > printf("host unknown\n"), exit(3); > if (invalidip(host_addr)) > printf("invalid IP\n"), exit(4); > } else { > service.sin_addr.s_addr = inet_addr(ip); > } > service.sin_port = htons(port); > service.sin_family = AF_INET; > > iResult = bind(ListenSocket, (struct sockaddr *)&service, > sizeof(service)); > if (iResult == -1) { > perror("bind"); > shutdown(ListenSocket, SHUT_RDWR); > return 1; > } > listen(ListenSocket, SOMAXCONN); > printf("SOMAXCONN=%d %d\n", SOMAXCONN, FD_SETSIZE); > /* all sockets are put into an own array_of_fs */ > /* in the while() loop below the FD_SET id used by looping through > the */ > /* array_of_fds to fill the readfds array in the select() */ > > enter(ListenSocket); > > /* > * Wait for connect > */ > tv.tv_sec = 0; > tv.tv_usec = 5000000; /* 5 seconds */ A friendly soul on FreeBSD-hackers told me that my tv_usec value is wrong in the timeval struct above. FreeBSD checks if it is in the range of 0<tv_usec<1000000 and not negative. How I came to think that the socket could be the invaid parameter, I don't know. Maybe I did two changes to the code at once and was blaming the wrong one. Thanks anyway for listening. -- Christoph
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4E36C1B1.4090708>