Re: select()/socket has problems under 2.2.x.

Frederick (niles@axp745.gsfc.nasa.gov)
Fri, 12 Feb 99 23:35:34 -0500


> OK here's the problem! The code is (effectively) setting:
>
> int sockbuflen = 0;
> setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
> (char *)&sockbuflen, sizeof sockbuflen);
>

I've included a sample client program that demos the problem. You'll
still need something to act as a server. I set the default to port 23
which is the default telnetd port so that should work for most people.
If select() works you'll see:

Got input...

at least once...else it's not working or telnetd isn't running.

I believe everyone running Linux 2.2.x should be able to reproduce
this problem.

I wouldn't mind some feedback on simply if others can reproduce the
problem or not. If not, try really small values like 0.

Thanks,
Rick Niles.

------------------
/* ANSI C headers */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <stdarg.h>

/* POSIX Unix headers */
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

/* Network headers */
#include <netdb.h>
#include <sys/socket.h> /* for AF_INET */
#include <netinet/in.h>
#include <arpa/inet.h>

#define ERROR -1
#define SOCKBUFLEN 0
#define MAXLEN 80

static int input_connect(char *host, unsigned short port)
{
struct sockaddr_in server; /* input socket address */
struct hostent *hp; /* hosts table entry for source */
int length; /* argument to getsockname() */
int sock; /* source socket file descriptor */

int sockbuflen = 1008; /* 1009 should work OK */
int size=sizeof(int);

/* create input socket */
sock = socket(AF_INET, SOCK_STREAM, 0);
server.sin_family = AF_INET;
server.sin_port = htons(port);
hp = gethostbyname(host);
memcpy((char *) &server.sin_addr, (char *) hp->h_addr,
hp->h_length);
connect(sock, (struct sockaddr *) &server,
sizeof(server));

length = sizeof server;
getsockname(sock, (struct sockaddr *) &server,
&length);

#if 1
setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
(char *)&sockbuflen, sizeof sockbuflen);
perror("setsockopt");
#endif
#if 1
getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
(char *)&sockbuflen, &size);
perror("getsockopt");
#endif
fprintf(stderr, "input connected to %s, port %d from"
"local port %d, fd=0x%x\n",
host,
port, ntohs(server.sin_port),
sock);
fprintf(stderr, "length is %d, size is %d\n",
sockbuflen, size);

while(1)
{
fd_set rfds;
char buf[MAXLEN];

FD_ZERO(&rfds);
FD_SET(sock, &rfds);

(void) fprintf(stderr, "Waiting for input...\n");
select(sock+1, &rfds, NULL, NULL, NULL);

(void) fprintf(stderr, "Got input...\n");

recv(sock, buf, MAXLEN, 0);
}

return sock;
}

int
main()
{
int sock;
sock = input_connect("localhost", 23); /* port 23 is telnet */
close(sock);
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/