From: Torge.Schmidt@arbi.informatik.uni-oldenburg.de (Torge Schmidt)
Subject: asynchronous socket i/o doesn't work
Organization: University of Oldenburg, Germany
Date: Wed, 30 Dec 1992 23:08:18 GMT


Hi there!

I'm trying to program an application using asynchronous socket
i/o. I do the work on an ODT 1.1 (= SCO Unix SysV R3.2.2) PC
simultanously to a SPARC 1+ running SunOS 4.1.2. 

A data server waits for connections (accept()). If it gets one,
about 4400 byte of data is sent to the data client in one
message. (I tried write()/read() and send()/recv(), both yield
the same result). The data client will be a X-Application, so it
will loop in XNextEvent(). But in regular intervalls, the data
server sends updated infos, which should be received and
processed by the client immediately, hence asynchronous i/o. I
followed the procedure described in 'Network Programmers Guide'
from AT&T (actually, the title is german, so don't be confused, if
you never heard about) and the SunOS-Answerbook (which shows the
same info as given by AT&T). The problem is, the client never
receives the SIGIO (on SunOS) / SIGPOLL (on ODT) signal. If I send the
signal manually to the client, it works for this instance. 

Here is an excerpt of the code of the client.
main () {
	...
	establish_connection(...);	/* sets up socket an signal handler
								(see below) */
	pause();					/* wait for signal */
	display_received_data();
	...
}



now the interesting part, the socket-initializing-routine:


/*
**	Verbindung aufbauen
*/
void
establish_connection (
	...
	)
{
	...

	/* Socket bereitstellen */
	sock	=  socket (hostp->h_addrtype, SOCK_STREAM, 0);
	if (sock < 0)
		FATAL ("establish_connection", "socket", "");


/* i suspected connect() and the first recv() being processed
before the signal handler was set up, so I moved connect() behind
the initialization. no success */

	/* Socket non-blocking machen */

/* this should not be necessary, as the client gets informed, when we get
data. Nevertheless, if I remove it, it won't work either */

	if (fcntl (sock, F_SETFL, (fcntl (sock, F_GETFL, 0) | O_NDELAY)) == -1)
		FATAL ("establish_connection", "fcntl", "setting socket non-blocking");

	/* Das Erscheinen von Nachrichten auf dem Socket erkennen */
	TESTLOG ("establish_connection", "setting signal handler for asynchronous socket i/o");

	signal (
#ifdef	sun
		SIGIO
#else
		SIGPOLL
#endif
		, data_arrived		/* Handler */
		);
	
/* neither process id (positive pid) nor process group id
(negative pid) worked in the following */


	{	int p	=  - getpid ();
		char	t [1000];


/* yeah, fcntl (sock, F_SETOWN, p) is the normal way (with
SunOS), but it didn't do it either */


		if (ioctl (sock, SIOCSPGRP, (char *) &p) < 0)
			FATAL ("establish_connection", "ioctl (SIOCSPGRP)"
				, "setting process group id for asynchronous socket i/o");

		if (ioctl (sock, SIOCGPGRP, &p))
			FATAL ("establish_connection", "ioctl(SIOCGPGRP)"
				, "getting process group id for asynchronous socket i/o");

		sprintf (t, "process id of socket %d: %d"
			, sock, p
			);
		
		TESTLOG ("establish_connection()", t);
	}

	
#ifdef	sun
	
	if (fcntl (sock, F_SETFL, fcntl (sock, F_GETFL, 0) | FASYNC) < 0)
		FATAL ("establish_connection", "fcntl", "enabling asynchronous socket i/o");

#else

	{	int	on	=  1;

		if (ioctl (sock, FIOASYNC, &on) < 0)
			FATAL ("establish_connection", "ioctl (FIOASYNC)", "enabling asynchronous socket i/o");


/* desperation: trying STREAMS-ioctl()
*/

		if (ioctl (sock, I_SETSIG, S_INPUT) < 0)
			FATAL ("establish_connection", "ioctl (I_SETSIG)", "enabling asynchronous socket i/o");
	}

#endif

	/* Verbindung aufbauen */
	if (connect(sock, &sock_addr, sizeof (sock_addr)) < 0)
		FATAL ("establish_connection", "connect", "");
}


Well, that's it. Any ideas what I am doing wrong? If so, please
reply via email, as I haven't much time these days (guess why).

Thanx and a happy new year,
-- 
Torge

-----------------------------------------------------------------------------
Torge  Schmidt,  FB  10   Informatik,    Uni  Oldenburg,    D-2900  Oldenburg
Privat  : Stadskanaal 3,  D-2804 Lilienthal,  04298/55 33 (Anrufbeantworter!)
InterNet: Torge.Schmidt@arbi.informatik.uni-oldenburg.de IRC/Nightfall: Moram
-----------------------------------------------------------------------------
A signature ny is a projection from a set I into the set N.