HPlogo HP 9000 Networking: BSD Sockets Interface Programmer's Guide > Chapter 3 Advanced Topics for Stream Sockets

Sending and Receiving Data Asynchronously

» 

Technical documentation

Complete book in PDF

 » Table of Contents

 » Glossary

 » Index

Asynchronous sockets allow a user program to receive an SIGIO signal when the state of the socket changes. This state change can occur, for example, when new data arrives. Currently the user would have to issue a select system call in order to determine if data were available. If other processing is required of the user program, the need to call select can complicate an application by forcing the user to implement some form of polling, whereby all sockets are checked periodically. Asynchronous sockets allow the user to separate socket processing from other processing, eliminating polling altogether. select may still be required to determine exactly why the signal is being delivered, or to which socket the signal applies.

Generation of the SIGIO signal is protocol dependent. It mimics the semantics of select in the sense that the signal is generated whenever select returns true. It is generally accepted that connectionless protocols deliver the signal whenever a new packet arrives. For connection oriented protocols, the signal is also delivered when connections are established or broken, as well as when additional outgoing buffer space becomes available. Be warned that these assertions are guidelines only; any signal handler should be robust enough to handle signals in unexpected situations.

The delivery of the SIGIO signal is dependent upon two things. First, the socket state must be set as asynchronous; this is done using the FIOASYNC flag of the ioctl system call. Second, the process group (pgrp) associated with the socket must be set; this is done using the SIOCSPGRP flag of ioctl. The sign value of the pgrp can lead to various signals being delivered. Specifically, if the pgrp is positive, this implies that a signal should be delivered to the process whose PID is the absolute value of the pgrp. If the pgrp is negative, a signal should be delivered to the process group identified by the absolute value of the pgrp.

Any application that chooses to use asynchronous sockets must explicitly activate the described mechanism. The SIGIO signal is a "safe" signal in the sense that if a process is unprepared to handle it, the default action is to ignore it. Thus any existing applications are immune to spurious signal delivery.

Notification that out-of-band data has been received is also done asynchronously; see the section "Sending and Receiving Out-of-band Data" in this chapter for more details.

The following example sets up an asynchronous SOCK_STREAM listen socket. This is typical of an application that needs to be notified when connection requests arrive.

int ls;           /* SOCK_STREAM listen socket initialized */
int flag = 1; /* for ioctl, to turn on async */
int iohndlr(); /* the function which handles the SIGIO */

signal (SIGIO, iohndlr); /* set up the handler */

if (ioctl (ls, FIOASYNC, &flag) == -1) {
perror ("can't set async on socket");
exit(1);
}
flag = -getpid();/* process group negative = deliver to process */
if (ioctl (ls, SIOCSPGRP, &flag) == -1) {
perror ("can't set pgrp");
exit(1);
}
/* signal can come any time now */

The following example illustrates the use of process group notification. Note that the real utility of this feature is to allow multiple processes to receive the signal, which is not illustrated here. For example, the socket could be of type SOCK_DGRAM; a signal here can be interpreted as the arrival of a service-request packet. Multiple identical servers could be set up, and the first available one could receive and process the packet.

int flag = 1;               /* ioctl to turn on async */
int iohndlr();
signal (SIGIO, iohndlr);

setpgrp(); /* set my processes' process group */
if (ioctl (s, FIOASYNC, &flag) == -1) {
perror ("can't set async on socket");
exit(1);
}
flag = getpid(); /* process group + = deliver to each process in group */
if (ioctl (s, SIOCSPGRP, &flag) == -1) {
perror ("can't set pgrp");
exit(1);
}
/* signal can come any time now */
© 1997 Hewlett-Packard Development Company, L.P.