asynchronous I/O & non-blocking connection establishment

asynchronous I/O & non-blocking connection establishment

Post by Boris Breme » Tue, 29 Oct 1996 04:00:00



Hi, I am looking for a portable method to get asynchronous notification
when the result of a TCP connection establishment attempt is available.
Below is a test program which seems to work fine on BSDI/Irix/Linux but
fails on Solaris, where no signal is delivered (but hitting ^C shows
that the socket is, for example, connected). Therefore my question: is
it my code that is flawed or Solaris' or is this functionality not at
all guaranteed with sockets ? (unlike the TLI interface). To state more
precisely, the problem occures if connecting to a server which doesn't
send any greeting after the connection establishment, eg. the discard
service.

If in the case of the SVR4 STREAMS subsystem non-blocking connection
requests are handled by filling sockmod's write queue, why doesn't
ioctl(fd, I_SETSIG, S_OUTPUT) do the trick ?

-bbr

------------------ usage: a.out address port -------------------------

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/file.h>
#include <errno.h>
#include <stdio.h>

#ifdef STREAMS
#include <stropts.h>
#endif

int sock;

void handler(int sig)
{
    struct sockaddr a;
    int n = sizeof(a);
    fd_set wset;
    struct timeval tv;

    switch (sig) {
    case SIGIO: printf("SIGIO "); break;
    case SIGINT: printf("SIGINT "); break;
    case SIGURG: printf("SIGURG ");
    }

    tv.tv_sec = tv.tv_usec = 0;
    FD_ZERO(&wset);
    FD_SET(sock, &wset);

    if (select(sock + 1, NULL, &wset, NULL, &tv) > 0) {
        if (FD_ISSET(sock, &wset)) {
            if (getpeername(sock, &a, &n))
                printf("not connected\n");
            else
                printf("connected\n");
            exit(0);
        }
    } else
        printf("not writable\n");

    if (sig == SIGINT)
        exit(0);

Quote:}

main(int argc, char *argv[])
{
    int fl, alen;
    pid_t pid = getpid();
    struct sigaction act;
    struct sockaddr_in addr;

    alen = sizeof(addr);
    memset(&addr, 0, alen);
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(argv[1]);
    addr.sin_port = htons(atoi(argv[2]));

    act.sa_handler = handler;
    act.sa_flags = 0;
    sigemptyset(&act.sa_mask);
    sigaction(SIGIO, &act, NULL);
    sigaction(SIGINT, &act, NULL);
    sigaction(SIGURG, &act, NULL);

    sock = socket(PF_INET, SOCK_STREAM, 0);
    fl = fcntl(sock, F_GETFL, 0);
    fcntl(sock, F_SETFL, fl |= O_NONBLOCK);

#ifdef STREAMS
    if (ioctl(sock, I_SETSIG, S_OUTPUT) < 0) {
        perror("I_SETSIG");
        exit(1);
    }
#else
    fcntl(sock, F_SETOWN, pid);
    fcntl(sock, F_SETFL, fl | FASYNC);
#endif

    if (connect(sock, (struct sockaddr *) &addr, alen) < 0) {
        /* errno == EINPROGRESS */
        for (;;)
            pause();
    } else {
        printf("main: connected\n");
    }

Quote:}

 
 
 

1. non-blocking, asynchronous socket use?

        There was a post recently containing an example (which didn't work)
program which attempted to receive from a socket asynchronously.
That is to say a function was supposed to be called when there was
data on the stream to be read.  In doing a bit of research I've heard
that setting up a non-blocking socket on a Sun machine is sometimes tricky.
I assume this is a prerequisite for asynchronous handling of incoming stream
data.
        To make a long story short, I'm interested in hearing how
this type of communication is set up.  More specifically,

1) How do you specify a function that is to be called when there is
data to be read on a socket.  Is this mode available with both stream
and datagram type sockets?  Is it done using the sigvec() and fcntl()
functions?

2) Is checking for data each time through a server's main loop and processing
it if it exists a valid method?  If so can I set up some sort of loop to
process an however many datagrams have been sent in since the last time through
the server's loop?

        I'm trying to write a game server which catches the client's
real-time key-presses as they happen.  I assumed that datagrams are the way
to go since a stream connection might cause a significant slowdown of
the supposedly real-time updating of the game scene (due to errors in
 transmission having to time out before they are retransmitted.)

        I'd really appreciate it if anyone could give me some good advice
or point me to some sample code.  I'll return the favor by sending them some
nice C++ objects that will (hopefully) make network communication a snap.  Of
course I'll have to finish them first...

        Thanks a lot y'all,

                DavE

2. regex help

3. Blocking & Non-Blocking

4. Linux / Apple Notebook compatability questions

5. Concurrent, non-(blocking&&threaded&&forking) server

6. Linux workstation & internet

7. Efficient way to wait for a non-blocking socket connection?

8. include - where the hell is it???

9. Problem making accept() non-blocking (never sees connections)

10. How to check connection loss in non-blocking mode

11. Asynchronous and non blocking

12. Blocking connect() fails, non-blocking succeeds?

13. Blocking and Non-Blocking socket