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>