[comp.unix.wizards] Multiple connections on a single port?

dsg@mbunix.mitre.org (David S. Goldberg) (01/05/89)

I appologize if this question is incredibly simple or obvious...

I am relatively new to interprocess communication programming.  What I would
like to do is have a server (that runs as a daemon) listen(2) on a port, and
have clients connect(2) to it over that port.  I had thought that by
fork(2)ing off the routine to communicate with the client, then close(2)ing
the accepted socket in the parent and looping back to the accept(2) call,
another client would be able to connect to the server and processing would
begin for that client without having to wait for the first one to finish.
But that hasn't been happening - the second connection doesn't get through
until the first one has completed and exited.  I know this can be done - I
can have multiple connections to the sendmail port, but I must be doing
something wrong here, and can't figure it out.  Any help would be greatly
appreciated.

I based my server on the sample given in the article "A 4.2BSD Interprocess
Communication Primer" by Leffler, Fabry and Joy found in the Ultrix
Supplementary Documents.  I also looked through the sources for rlogind and
sendmail, but I am unable to see what they are doing differently.

Follows is a basic skeleton of the server as it stands so far.  Error
checking, #includes/defines and the stuff that interacts with the client
have been omitted for brevity.

----------------------------------------------------------------------

main(argc,argv)
int argc;
char **argv;
{
	int f,g,len;
	struct sockaddr_in sin, from;
	struct servent *sp;

	sp = getservbyname("authent","tcp");
/*
 * become a daemon
 */
	sessdetach(); /* a routine based on an article in ;login - sorry I
forget which issue */

	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = INADDR_ANY;
	sin.sin_port = sp->s_port;
	f = socket(AF_INET,SOCK_STREAM,0);
	bind(f,(caddr_t)&sin,sizeof(sin));
	signal(SIGCHLD,reaper); /* to clean up afterwards - wait3(2) */
	listen(f,5)
	for(;;) {
		register int pid;
		register struct hostent *hp;
		char *hname;
		do {
			len = sizeof(from);
			errno = 0;
			g = accept(f,&from,&len);
		} while (g < 0 && errno == EINTR);
		from.sin_port = ntohs((u_short)from.sin_port);
		hp = gethostbyaddr(&from.sin_addr, sizeof (struct in_addr),
			from.sin_family);
		hname = (char *) malloc(strlen (hp->h_name) + 1);
		strcpy(hname,hp->h_name);
		if (approved(hname)) { /* only certain hosts can connect */
			if ((pid = fork()) == 0) {
				close(f);
				authenticate(g); /* routine talks to client*/
				return;
			}
			close(g);
		}
		else close(g);
	}
}

Thanks in advance for any help

-dave
--------------------------------------------------------------------------
Dave Goldberg	             ARPA: dsg@mitre.org
The Mitre Corporation
MS B020                      UUCP: linus!mbunix!dsg
Bedford, MA 01730
617-271-2460

dsg@mbunix.mitre.org (David S. Goldberg) (01/07/89)

In article <43380@linus.UUCP> I writes:
>
>I appologize if this question is incredibly simple or obvious...

	And after discovering my stupid mistake, I really appolgize :-)

[problem with multiple connections being cued]

>----------------------------------------------------------------------
>
>main(argc,argv)
>int argc;
>char **argv;
>{

[ no need to see all the gory details again]

>			g = accept(f,&from,&len);
>		} while (g < 0 && errno == EINTR);
>		from.sin_port = ntohs((u_short)from.sin_port);
>		hp = gethostbyaddr(&from.sin_addr, sizeof (struct in_addr),
>			from.sin_family);
>		hname = (char *) malloc(strlen (hp->h_name) + 1);
>		strcpy(hname,hp->h_name);
>		if (approved(hname)) { /* only certain hosts can connect */
>			if ((pid = fork()) == 0) {
>				close(f);
>				authenticate(g); /* routine talks to client*/
>				return;
				^^^^^^^

ARRGH I should have used exit.  And looking through my RCS logs, I found
that at one point I had.  I don't even remember changing it.  I think the
reason why is that the descriptor g doesn't close properly, but could
someone tell me for sure?

>			}
>			close(g);
>		}
>		else close(g);

Thanks,

-dave
--------------------------------------------------------------------------
Dave Goldberg	             ARPA: dsg@mitre.org
The Mitre Corporation
MS B020                      UUCP: linus!mbunix!dsg
Bedford, MA 01730
617-271-2460