Date: Wed, 6 Feb 2002 13:16:31 -0800 (PST) From: ccloud <ccloud@inteqrx.com> To: freebsd-gnats-submit@FreeBSD.org Subject: misc/34673: Second call to select() waits ~100ms before data available Message-ID: <200202062116.g16LGVC52299@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 34673
>Category: misc
>Synopsis: Second call to select() waits ~100ms before data available
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Feb 06 13:20:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: ccloud
>Release:
>Organization:
Inteq
>Environment:
FreeBSD switch.in.net 4.2-RELEASE FreeBSD 4.2-RELEASE #8: Tue Aug 21 14:55:44
CDT 2001 root@switch1.in.net:/usr/src/sys/compile/SWITCH i386
>Description:
I've inherited a tradition client/server application. The client connects to the server, receives 2 messages from the server, then goes aways. The client sits in the select() waiting for the messages. The first message is received by the client within 1ms of when the sever sent it. The client then calls select() again (almost immediately). The sever sends the second message but the select returns only about 100ms from the receipt of the first message.
Here are some timestamps of the programs below:
Server:
Waiting for connection
TIME: 1013027320.232152 send
TIME: 1013027320.232411 send done
TIME: 1013027320.262219 send
TIME: 1013027320.262310 send done
Client:
TIME: 1013027320.219166 getIo select
TIME: 1013027320.232327 getIo select done
Read data 20
TIME: 1013027320.252139 getIo select
TIME: 1013027320.332200 getIo select done
Read data 370
Notice the server sent the second message at .262219 but the client didn't receive it until .332200 about 100ms after the first message was received at .232327
Both programs are the only programs running on the same machine.
>How-To-Repeat:
*************************** CLIENT ********************************
static struct timeval timeit;
#define TIMEITHERE(STR) gettimeofday(&timeit,0); \
fprintf(stderr,"TIME: %ld.%.6ld %s\n", timeit.tv_sec, timeit.tv_usec,STR);
/*
** connect to remote host
*/
int connectTo(host, service, attempts)
char *host;
char *service;
int attempts;
{
int l_socket; /* listen socket */
u_short s_port; /* service port number */
struct in_addr host_ip; /* remote host IP - "in.h" */
struct sockaddr_in s_name; /* socket address - "in.h" */
int i;
int ret;
s_port = htons(atoi(service));
if ((ret=inet_aton(host, &host_ip)) == 0) {
return(-1);
}
bzero((char *) &s_name, sizeof(s_name));
s_name.sin_family = AF_INET;
s_name.sin_port = s_port;
s_name.sin_addr.s_addr = host_ip.s_addr;
signal(SIGTERM, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_IGN);
signal(SIGALRM, SIG_IGN);
/*
** get a socket
*/
for (i=0, ret=-1; i<10 && ret<0; ++i) {
if ((l_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
return(-1);
}
ret=connect(l_socket, (struct sockaddr *)&s_name, sizeof(s_name));
if (ret < 0) {
fprintf(stderr,"Error(connect): %s\n", strerror(errno));
close(l_socket);
usleep(100*1000);
}
}
if (ret < 0) return(-1);
return(l_socket);
}
int getIo(fd ,buf, len)
int fd; /* input socket file descriptor */
char *buf; /* buffer to hold data for transfer */
int len; /* length of data or len og buffer */
{
fd_set fdset; /* file descptors set */
int event; /* event on the given socket */
int ret;
struct timeval timeout;
timeout.tv_sec = (time_t)1000;
timeout.tv_usec = (time_t)0;
FD_ZERO( &fdset );
FD_SET(fd, &fdset);
TIMEITHERE("getIo select");
event = select(fd+1, &fdset, NULL, NULL, &timeout);
TIMEITHERE("getIo select done");
if (event == 0) {
fprintf(stderr, "Timed out\n");
sleep(1);
return(-1);
}
if (event < 0) {
fprintf(stderr, "SELECT ERROR - errno %d\n",errno);
return(-1);
}
if (! FD_ISSET(fd, &fdset)) {
fprintf(stderr, "Not our socket ????\n");
usleep(5*1000);
}
buf[0] = '\0';
ret = read(fd, buf, len);
if (ret < 0) {
fprintf(stderr, "READ ERROR errno=%d\n",errno);
} else if (ret == 0) {
fprintf(stderr, "READ ERROR zero\n");
} else {
fprintf(stderr, "Read data %d\n",ret);
buf[ret] = '\0';
}
return(ret);
}
int main( int argv, char* argc[] )
{
char buf[1024];
int fd;
fd = connectTo("192.168.100.119", "9801");
getIo(fd, buf, 20);
usleep(10*1000);
getIo(fd, buf, 370);
sleep(5);
return 0;
}
****************************** SERVER *******************************
static struct timeval timeit;
#define TIMEITHERE(STR) gettimeofday(&timeit,0); \
fprintf(stderr,"TIME: %ld.%.6ld %s\n", timeit.tv_sec, timeit.tv_usec,STR);
/*
** SEND IO over connected socket
*/
int sendIo(fd ,buf, len)
int fd; /* input socket file descriptor */
char *buf; /* buffer to hold data for transfer */
int len; /* length of data or len og buffer */
{
int ret;
TIMEITHERE("send");
ret = write(fd, buf, len);
TIMEITHERE("send done");
if ( ret < 0 ) {
fprintf(stderr, "WRITE ERORR - errno %d\n",errno);
}
return(ret);
}
int doserver(host, service, attempts)
char *host;
char *service;
int attempts;
{
int l_socket; /* listen socket */
int a_socket; /* accept socket */
int in_fd; /* input/output socket */
u_short s_port; /* service port number */
struct sockaddr_in s_name; /* binding socket name */
struct sockaddr_in c_name; /* connected socket name */
int on = 1; /* socket level opt value on */
char *oval = (char *) &on;
int osz=sizeof(on); /* socket option value size */
int olvl=SOL_SOCKET;/* socket option level */
int i, j, ret;
struct in_addr host_ip; /* remote host IP - "in.h" */
s_port = htons(atoi(service));
if ((ret=inet_aton(host, &host_ip)) == 0) {
return(-1);
}
bzero((char *) &s_name, sizeof(s_name));
s_name.sin_family = AF_INET;
s_name.sin_port = s_port;
s_name.sin_addr.s_addr = host_ip.s_addr;
do {
if ((l_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
fprintf(stderr,"Error(socket): %s", strerror(errno));
exit(-1);
}
if (setsockopt(l_socket, olvl, SO_KEEPALIVE, oval, osz) < 0) {
fprintf(stderr,"Error(setsock1): %s", strerror(errno));
exit(-1);
}
if (setsockopt(l_socket, olvl, SO_REUSEADDR, oval, osz) < 0) {
fprintf(stderr,"Error(setsock2): %s", strerror(errno));
exit(-1);
}
if (setsockopt(l_socket, olvl, SO_REUSEPORT, oval, osz) < 0) {
fprintf(stderr,"Error(setsock3): %s", strerror(errno));
exit(-1);
}
ret=bind(l_socket,(struct sockaddr *)&s_name,sizeof(s_name));
if (ret<0) {
fprintf(stderr,"Error(bind): %s", strerror(errno));
exit(-1);
}
listen(l_socket, 0);
j = 0;
do {
fprintf(stderr,"Waiting for connection\n");
i = sizeof(c_name);
a_socket=accept(l_socket,(struct sockaddr *)&c_name,&i);
if (a_socket >= 0) {
close(l_socket);
} else {
++j;
fprintf(stderr,"Error(accept): %s", strerror(errno));
usleep(1000);
}
} while (a_socket < 0 && j < 100);
if (a_socket < 0) {
ret = -1;
continue;
}
} while(a_socket < 0);
return(a_socket);
}
int main( int argv, char* argc[] )
{
char buf[1024];
int fd;
int ret,i;
fd = doserver("192.168.100.119", "9801");
sprintf(buf,"11111222223333344444");
usleep(10*1000);
ret = sendIo(fd, buf, strlen(buf));
usleep(20*1000);
buf[0] = '\0';
for(i=0; i<37; i++)
strcat(buf,"0123456789");
ret = sendIo(fd, buf, strlen(buf));
sleep(1);
}
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200202062116.g16LGVC52299>
