# DIGITAL TCP/IP Services for OpenVMS
System Services and C Socket Programming

Previous | Contents

The following options are available at the socket level:

- SO_REUSEADDR indicates that the rules used in validating addresses supplied in a bind() call should allow reuse of local addresses.
- SO_KEEPALIVE keeps connections alive by enabling the periodic transmission of messages on a connected socket. Should the connected party fail to respond to these messages, the connection is considered broken and processes using the socket are notified through an EPIPE error.
- SO_DONTROUTE indicates that outgoing messages should bypass the standard routing facilities. Instead, messages are directed to the appropriate network interface according to the network portion of the destination address.
- SO_LINGER controls the actions taken when unsent messages are queued on the socket and a close() is performed. By default, transmitted data is purged from the socket when the close() is performed. SO_LINGER delays the internal socket deletion portion of close() until either the data has been transmitted or the device times out (in approximately 8 minutes).
- SO_BROADCAST is used to enable or disable broadcasting on the socket. Table 6-3 describes the socket options.

If you include the UCX$INETDEF definition file, you can use the options listed in Tables 6-3, 6-4, and 6-5.

Table 6-3 Communications Socket Options
Socket Option | Description
--- | ---
UCX$C_RCVBUF | Sets the socket receive quota. This option requires a system UIC, SYSPRV, BYPASS, or OPER privilege to be set.
UCX$C_SNDBUF | Sets the socket send quota. This option requires a system UIC, SYSPRV, BYPASS, or OPER privilege to be set.
UCX$C_NO_RCV_CHECKSUM | Disables checksum calculation for received data.
UCX$C_NO_SND_CHECKSUM | Disables checksum calculation for transmitted data.
UCX$C_NO_CHECKSUM | Disables checksum calculation altogether.

Unsupported socket options are ignored. You normally set and clear options with item_list descriptors.

Table 6-4 TCP/IP Options
TCP/IP Option | Description
--- | ---
UCX$C_USELOOPBACK | Shortcuts the data transfer when the transfer is local to the host. This improves the performance of the local TCP/IP transfer process and results in a lower load on the CPU when applications using local transfer are active.
UCX$C_TCP_NODELAY | Specifies that the send operation will not be delayed to coalesce packets.
UCX$C_TCP_PROBE_IDLE | Specifies the time interval for the KEEPALIVE probe, as well as for the connection establishing the timeout.
UCX$C_TCP_DROP_IDLE | Specifies the time interval after which the connection is dropped.
UCX$C_FULL_DUPLEX_CLOSE | Returns an EPIPE error (SS$_LINKDISCON) the first time data is sent after the peer has closed its half of the connection. Subsequent send operations on the half-closed socket proceeds normally.

Table 6-5 IP Options
IP Option | Description
--- | ---
UCX$C_IP_TTL | Time to live for a datagram
UCX$C_IP_TOS | Type of service (1-byte value)

### optval

Points to a buffer containing the parameters of the specified option.

All socket level options other than SO_LINGER should be nonzero if the option is to be enabled, or zero if it is to be disabled.

SO_LINGER uses a linger structure parameter defined in the <socket.h> file. This structure specifies the desired state of the option and the linger interval. The option value for the SO_LINGER command is the address of a linger structure. See Section 5.8.4 for a description of the linger structure.

If the socket promises reliable delivery of data and l_onoff is nonzero, the system blocks the process on the close() attempt until it is able to transmit the data or until it decides it is unable to deliver the information. A timeout period, called the linger interval, is specified in l_linger.

If l_onoff is set to zero and a close() is issued, the system processes the close in a manner that allows the process to continue as quickly as possible.

### optlen

An integer containing the size of the buffer pointed to by optval.

## DESCRIPTION

> This routine manipulates options associated with a socket. Options can exist at multiple protocol levels. They are always present at the uppermost socket level.

> When manipulating socket options, specify the level at which the option resides and the name of the option. To manipulate options at the socket level, specify level as SOL_SOCKET. To manipulate options at any other level, supply the protocol number of the appropriate protocol controlling the option. For example, to indicate that an option is to be interpreted by TCP, set the level to the protocol number (IPPROTO_TCP) of TCP. See <in.h> for the various IPPROTO values.

## Return Values

> 0 | Successful completion.
> --1 | Error; errno is set to indicate the error.

## Errors

> You can set errno to the following values:
> [EBADF] | The descriptor is invalid.
> [ENOTSOCK] | The socket descriptor references a file, not a socket.
> [ENOPROTOOPT] | The option is unknown.
> [EFAULT] | The optname parameter is not a valid part of the user address space.

# vaxc$get_sdc()

> Returns the socket device channel (SDC) associated with a socket descriptor for direct use with DIGITAL TCP/IP Services for OpenVMS software.

> > Note

> > This routine only works with VAX C. Use the decc$get_sdc() routine with DEC C.

## Format

> ### #include <socket.h>

> ### short int vaxc$get_sdc (int s);

## ARGUMENT

> ### s

> A socket descriptor.

## DESCRIPTION

> This routine returns the SDC associated with a socket. C Socket descriptors are normally used either as file descriptors or with one of the routines that takes an explicit socket descriptor as its argument. C Sockets are implemented using TCP/IP socket device channels. This routine returns the SDC used by a given socket descriptor so you can use the TCP/IP facilities directly by means of various I/O system services ($QIO).

> > Note

> > The 64-bit return from OpenVMS Alpha systems has zero-extended bits in the high 32 bits of R0.

## Return Values

> 0 | Indicates that s is not an open socket descriptor.
> x | The SDC number.

# Chapter 7
Error Codes

This chapter contains a table of C Socket error codes and their OpenVMS system service equivalents. The C Socket routines use the DEC C compiler.

Table 7-1 Translation of Socket Error Codes to OpenVMS Error Codes
C Socket (DEC C) Error Code | Meaning | OpenVMS System Service Error Code
--- | --- | ---
0 | (success) | SS$_NORMAL
1 EPERM | Not owner | SS$_ABORT
2 ENOENT | No such file or directory | SS$_ABORT
3 ESRCH | No such process | SS$_NOSUCHNODE
4 EINTR | Interrupted system call | SS$_ABORT
5 EIO | I/O error | SS$_ABORT
6 ENXIO | No such device or address | SS$_NOSUCHDEV
7 E2BIG | Argument list too long | SS$_ABORT
8 ENOEXEC | Execution format error | SS$_ABORT
9 EBADF | Bad file number | SS$_BADPARAM
10 ECHILD | No children | SS$_ABORT
11 EAGAIN | No more processes | SS$_ABORT
12 ENOMEM | Not enough core | SS$_INSFMEM
13 EACCES | Permission denied | SS$_ABORT
14 EFAULT | Bad address | SS$_ACCVIO
15 ENOTBLK | Block device required | SS$_ABORT
16 EBUSY | Mount device busy | SS$_ABORT
17 EEXIST | File exists | SS$_FILALRACC
18 EXDEV | Cross-device link | SS$_ABORT
19 ENODEV | No such device | SS$_ABORT
20 ENOTDIR | Not a directory | SS$_ABORT
21 EISDIR | Is a directory | SS$_ABORT
22 EINVAL | Invalid argument | SS$_BADPARAM
23 ENFILE | File table overflow | SS$_ABORT
24 EMFILE | Too many open files | SS$_ABORT
25 ENOTTY | Not a typewriter | SS$_ABORT
26 ETXTBSY | Text file busy | SS$_ABORT
27 EFBIG | File too large | SS$_ABORT
28 ENOSPC | No space left on device | SS$_ABORT
29 ESPIPE | Illegal seek | SS$_ABORT
30 EROFS | Read-only file system | SS$_ABORT
31 EMLINK | Too many links | SS$_ABORT
32 EPIPE | Broken pipe | SS$_LINKDISCON
33 EDOM | Argument too large | SS$_BADPARAM
34 ERANGE | Result too large | SS$_TOOMUCHDATA
35 EWOULDBLOCK | Operation would block | SS$_SUSPENDED
36 EINPROGRESS | Operation now in progress | SS$_ABORT
37 EALREADY | Operation already in progress | SS$_ABORT
38 ENOTSOCK | Socket operation on non-socket | SS$_NOTNETDEV
39 EDESTADDRREQ | Destination address required | SS$_NOSUCHNODE
40 EMSGSIZE | Message too long | SS$_TOOMUCHDATA
41 EPROTOTYPE | Protocol wrong type for socket | SS$_PROTOCOL
42 ENOPROTOOPT | Protocol not available | SS$_PROTOCOL
43 EPROTONOSUPPORT | Protocol not supported | SS$_PROTOCOL
44 ESOCKTNOSUPPORT | Socket type not supported | SS$_PROTOCOL
45 EOPNOTSUPP | Operation not supported on socket | SS$_ILLCNTRFUNC
46 EPFNOSUPPORT | Protocol family not supported | SS$_PROTOCOL
47 EAFNOSUPPORT | Address family not supported | SS$_PROTOCOL
48 EADDRINUSE | Address already in use | SS$_DUPLNAM
49 EADDRNOTAVAIL | Requested address cannot be assigned | SS$_IVADDR
50 ENETDOWN | Network is down | SS$_UNREACHABLE
51 ENETUNREACH | Network is unreachable | SS$_UNREACHABLE
52 ENETRESET | Network dropped connection on reset | SS$_RESET
53 ECONNABORTED | Software caused connection abort | SS$_LINKABORT
54 ECONNRESET | Connection reset by peer | SS$_CONNECFAIL
55 ENOBUFS | No buffer space available | SS$_INSFMEM
56 EISCONN | Socket is already connected | SS$_FILALRACC
57 ENOTCONN | Socket is not connected | SS$_NOLINKS
58 ESHUTDOWN | Cannot send after socket shutdown | SS$_SHUT
59 ETOOMANYREFS | Too many references, cannot splice | SS$_ABORT
60 ETIMEDOUT | Connection timed out | SS$_TIMEOUT
61 ECONNREFUSED | Connection refused | SS$_REJECT
62 ELOOP | Too many levels of symbolic links | SS$_ABORT
63 ENAMETOOLONG | File name too long | SS$_ABORT
64 EHOSTDOWN | Host is down | SS$_SHUT
65 EHOSTUNREACH | No route to host | SS$_UNREACHABLE

# Appendix A
Online Program Examples

Table A-1 lists the sample programs printed in this appendix. See Table 1-1 and Table 1-2 for a complete list of all the sample programs provided online in UCX$EXAMPLES.

Table A-1 Location of Online Program Examples --- UCX$EXAMPLES:
File | See...
--- | ---
UCX$TCP_SERVER_QIO.C | Section A.1
UCX$UDP_SERVER_IPC.C | Section A.2
UCX$TCP_SERVER_IPC.C | Section A.3
UCX$TCP_SERVER_IPC_AUXS.C | Section A.4
UCX$TCP_CLIENT_IPC.C | Section A.5

# A.1 TCP/IP Server Using QIO Calls

Example A-1 shows a TCP/IP server using QIO calls. You can access this file online in UCX$EXAMPLES:UCX$TCP_SERVER_QIO.C.

Depending on your compiler, you can compile and link this program in any of the following ways:

- DEC C compiler:

      $ CC /PREFIX=ALL UCX$TCP_SERVER_QIO.C
      $ LINK UCX$TCP_SERVER_QIO

- DEC C++ compiler:

      $ CXX /PREFIX=ALL/DEFINE=VMS UCX$TCP_SERVER_QIO.C
      $ LINK UCX$TCP_SERVER_QIO

- VAX C compiler:
  To link this program with VAX C, you must have the following entries in your .opt file:

      SYS$LIBRARY:UCX$IPC.OLB/LIB
      SYS$SHARE:VAXCRTL.EXE/SHARE

  Then, you can link and compile as follows:

      $ CC /VAXC UCX$TCP_SERVER_QIO.C
      $ LINK UCX$TCP_SERVER_QIO, -
              SYS$LIBRARY:UCX$IPC/LIB, -
              SYS$INPUT/OPTIONS
      SYS$SHARE:UCX$IPC_SHR/SHARE
      SYS$SHARE:VAXCRTL.EXE/SHARE

Example A-1 TCP/IP Server Using QIO Calls

    #include <descrip.h>        /* OpenVMS descriptor information */
    #include <errno.h>          /* UNIX style error codes for I/O routines */
    #include <in.h>             /* Internet system constants and structures */
    #include <inet.h>           /* Network address information */
    #include <iodef.h>          /* I/O function code definitions */
    #include <lib$routines.h>   /* LIB$ RTL-routine signatures */
    #include <lib$routines.h>   /* LIB$ RTL-routine signatures */
    #include <netdb.h>          /* Network database library information */
    #include <signal.h>         /* UNIX style signal value definitions */
    #include <socket.h>         /* TCP/IP socket definitions */
    #include <ssdef.h>          /* SS$_<xyz> system service return status codes */
    #include <starlet.h>        /* System service calls */
    #include <stdio.h>          /* UNIX 'standard I/O' definitions   */
    #include <stdlib.h>         /* General utilities */
    #include <string.h>         /* String handling function definitions */
    #include <ucx$inetdef.h>    /* UCX network definitions */

    /* Convert short port number from host to network byte order */
    #define htons(x) ((unsigned short)((x<<8)|(x>>8)))

    main() {
            int     status;         /* For return status */
            short   channel;        /* INET channel */
            short   channel_1;      /* Template for ACCEPT */
            short   sck_parm[2];    /* Socket creation parameter */
            short   iosb[4];        /* I/O status block */

            char    buf[512];
            int     buflen = 512;   /* Buffer length */
            int     retval;
            short   port;
            unsigned char *dummy;
            unsigned int    r_retlen;
            int     one=1;
            struct  SOCKADDRIN local_host, remote_host;

            struct  IL2 {
                    unsigned int il2_length;
                    char *il2_address;
            } lhst_adrs;

            struct  IL3 {
                    unsigned int il3_length;
                    char *il3_address;
                    unsigned int* il3_retlen;
            } rhst_adrs;

            struct  dsc$descriptor inet_dev =
                    {10, DSC$K_CLASS_S, DSC$K_DTYPE_T, "UCX$DEVICE"};

     struct  { short len, param; int *ptr; }
                    item_list[] = {{sizeof(one), UCX$C_REUSEADDR, (int*)0 }},
                    options = {sizeof(item_list), UCX$C_SOCKOPT, (int*)0 };

            item_list[0].ptr = &one;
            options.ptr = (int*)item_list;

            lhst_adrs.il2_length = sizeof local_host;
            lhst_adrs.il2_address = (char *)&local_host;

            rhst_adrs.il3_length  = sizeof remote_host;
            rhst_adrs.il3_address = (char*)&remote_host;
            rhst_adrs.il3_retlen  = &r_retlen;

            sck_parm[0] = UCX$C_TCP;                    /* TCP/IP protocol */
            sck_parm[1] = INET_PROTYP$C_STREAM;         /* Stream type of socket */
            local_host.SIN$W_FAMILY = UCX$C_AF_INET;    /* INET family */
            local_host.SIN$L_ADDR = UCX$C_INADDR_ANY;   /* Any address */

            while (retval != 1) {
                    printf("Enter local port number:\n");
                    retval = scanf("%hd", &port);
                    if (retval == 1)
                            local_host.SIN$W_PORT = htons(port);
                    else scanf("%s",buf);    /* discard bad input */
            }

            /* Assign two channels to the UCX device. */
            status = sys$assign(&inet_dev, &channel, 0, 0);
            if (status & 1)
                    status = sys$assign(&inet_dev, &channel_1, 0, 0);
            if (!(status & 1)) {
                    printf("Failed to assign channel to UCX device.\n");
                    exit(status);
            }

           /* Create the socket and set the REUSEADDR option. */
           status = sys$qiow(3,             /* Event flag */
                            channel,        /* Channel number */
                            IO$_SETMODE,    /* I/O function */
                            iosb,           /* I/O status block */
                            0, 0,
                            &sck_parm, 0,   /* P1 socket creation parameter */
                            0, 0,
                            &options, 0);   /* P5 socket option descriptor */
            if (status & 1) status = iosb[0];
            if (!(status & 1)) {
                    printf("Failed to create the device socket.\n");
                    exit(status);
            }

            /* Bind to chosen port number (after REUSEADDR is set above). */
            status = sys$qiow(3,            /* Event flag */
                            channel,        /* Channel number */
                            IO$_SETMODE,    /* I/O function */
                            iosb,           /* I/O status block */
                            0, 0,
                            0, 0,
                            &lhst_adrs,     /* P3 local socket name */
                            3,              /* P4 connection backlog */
                            0, 0);
            if (status & 1) status = iosb[0];
            if (!(status & 1)) {
                    printf("Failed to bind the device socket.\n");
                    exit(status);
            }

            /* Accept a connection from a client. */
            status = sys$qiow(3,                    /* Event flag */
                            channel,                /* Channel number */
                            IO$_ACCESS|IO$M_ACCEPT, /* I/O function */
                            iosb,                   /* I/O status block */
                            0, 0,
                            0, 0,
                            &rhst_adrs,             /* P3 Remote IP address*/
                            &channel_1,             /* P4 Channel for new socket */
                            0, 0);
            if (status & 1) status = iosb[0];
            if (!(status & 1)) {
                    printf("Failed to accept a connection from a client.\n");
                    exit(status);
            }
            dummy = (unsigned char *)&remote_host.SIN$L_ADDR;
            printf("Connection from host: %d.%d.%d.%d, port: %d\n",
                    dummy[0], dummy[1], dummy[2], dummy[3],
                    htons(remote_host.SIN$W_PORT));

            /* Read I/O buffer. */
            status = sys$qiow(3,            /* Event flag */
                            channel_1,      /* Channel number */
                            IO$_READVBLK,   /* I/O function */
                            iosb,           /* I/O status block */
                            0, 0,
                            buf,            /* P1 buffer */
                            buflen,         /* P2 buffer length */
                            0, 0, 0, 0);
            if (status & 1) status = iosb[0];
            if (!(status & 1))
                     printf("Failed to read from socket.\n");

            /* If all is well, print message */
            printf ("Received text: %s\n", buf);

            /* Shut down the socket (optional). */
            status = sys$qiow(3,
                            channel_1,
                            IO$_DEACCESS|IO$M_SHUTDOWN,
                            iosb,
                            0, 0,
                            0, 0, 0,
                            UCX$C_DSC_ALL,    /* P4 Discard all packets */
                            0, 0);
            if (status & 1) status = iosb[0];
            if (!(status & 1))
                    printf("Failed to shut down the socket.\n");

            /* Close the sockets -- accepted and listener (optional). */
            status = sys$qiow(3,
                            channel_1,
                            IO$_DEACCESS,
                            iosb,
                            0, 0,
                            0, 0, 0, 0, 0, 0);
            if (status & 1) status = sys$qiow(3,
                            channel,
                            IO$_DEACCESS,
                            iosb,
                            0, 0,
                            0, 0, 0, 0, 0, 0);
            if (status & 1) status = iosb[0];
            if (!(status & 1))
                    printf("Failed to close the socket.\n");

            /* Deassign the UCX device channels. */
            status = sys$dassgn(channel_1);
            if (status & 1) status = sys$dassgn(channel);
            if (!(status & 1))
            printf("Failed to deassign the channel.\n");
    }

# A.2 UDP/IP Server --- C Socket Example

Example A-2 shows a UDP/IP server using the IPC socket interface. You can access this file online in UCX$EXAMPLES:UCX$UDP_SERVER_IPC.C.

This example shows you how to create a SOCK_DGRAM (UDP) socket type, bind it, and select it to receive a message on the socket. Error messages are printed to the screen.

This example is portable to UNIX. The include files are conditionally defined for both OpenVMS VAX and Alpha systems, and "perror" is used for error reporting.

The C Socket calls used in this program are:

- bind()
- close()
- gethostbyname()
- recvfrom()
- select()
- shutdown()
- socket()

Depending on your compiler, you can compile and link this program in any of the following ways:

- DEC C compiler:

      $ CC /PREFIX=ALL UCX$UDP_SERVER_IPC.C
      $ LINK UCX$UDP_SERVER_IPC

- DEC C++ compiler:

      $ CXX /PREFIX=ALL/DEFINE=VMS UCX$UDP_SERVER_IPC.C
      $ LINK UCX$UDP_SERVER_IPC

- VAX C compiler:
  To link this program with VAX C, you must have the following entries in your .opt file:

      SYS$LIBRARY:UCX$IPC.OLB/LIB
      SYS$SHARE:VAXCRTL.EXE/SHARE

  Then, you can link and compile as follows:

      $ CC /VAXC UCX$UDP_SERVER_IPC.C
      $ LINK UCX$UDP_SERVER_IPC, -
              SYS$LIBRARY:UCX$IPC/LIB, -
              SYS$INPUT/OPTIONS
      SYS$SHARE:UCX$IPC_SHR/SHARE
      SYS$SHARE:VAXCRTL.EXE/SHARE

Example A-2 UDP/IP Server Using the C Socket Interface

    #ifdef VMS
    #include <descrip.h>        /* OpenVMS descriptor information */
    #include <errno.h>          /* UNIX style error codes for I/O routines */
    #include <in.h>             /* Internet system constants and structures */
    #include <inet.h>           /* Network address information */
    #include <iodef.h>          /* I/O function code definitions */
    #include <lib$routines.h>   /* LIB$ RTL-routine signatures */
    #include <netdb.h>          /* Network database library information */
    #include <signal.h>         /* UNIX style signal value definitions */
    #include <socket.h>         /* TCP/IP socket definitions */
    #include <ssdef.h>          /* SS$_<xyz> system service return status codes */
    #include <starlet.h>        /* System service calls */
    #include <stdio.h>          /* UNIX 'standard I/O' definitions   */
    #include <stdlib.h>         /* General utilities */
    #include <string.h>         /* String handling function definitions */
    #include <ucx$inetdef.h>    /* UCX network definitions */
    #include <unixio.h>         /* Prototypes for UNIX emulation functions */

    #else
    #include <errno.h>
    #include <sys/types.h>
    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    #include <sys/uio.h>
    #include <time.h>  /* timeval declared here */
    #endif

    /*-----------------------------------------------------------*/

    cleanup( int socket )
    {
            int    retval;

            /*
             * Shut down socket completely.
             */
            retval = shutdown(socket,2);
            if (retval == -1)
                    perror ("shutdown");

            /*
             * Close socket.
             */
            retval = close (socket);
            if (retval)
            perror ("close");

            exit( 1 );

    } /* end cleanup */

    /*--------------------------------------------------------------------*/
    main( int argc, char **argv )
    {
            int     rmask, wmask, emask;
            int     sock_2;                         /* Socket 2  descriptor      */
            int     buflen,fromlen;
            char    recvbuf[BUFSIZ];
    static  struct  sockaddr_in sock1_name;     /* Address struct for socket1 */
    static  struct  sockaddr_in sock2_name;     /* Address struct for socket2 */
            int  namelength;
            struct  hostent         hostentstruct;  /* Storage for hostent data   */
            struct  hostent         *hostentptr;    /* Pointer to hostent data    */
            static  char            hostname[256];  /* Name of local host         */
            int     retval;
            int     flag;
            struct  timeval      timeout;

            /*
             * Check input parameters
             */
            if (argc != 2 )
                    {
                    printf("Usage: server portnumber.\n");
                    exit( 1 );
                    }

            /*
             * Open socket 2: AF_INET, SOCK_DGRAM.
             */
            if ((sock_2 = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
                    {
                    perror( "socket");
                    exit( 1 );
                    }

            /*
             * Get the local host  name.
             */
            retval = gethostname(hostname,sizeof hostname);
            if (retval)
                    {
                    perror ("gethostname");
                    cleanup(sock_2);
                    }

            /*
             * Get pointer to network data structure for local host.
             */
            if ((hostentptr = gethostbyname (hostname)) == NULL)
                    {
                    perror( "gethostbyname");
                    cleanup(sock_2);
                    }

            /*
             * Copy hostent data to safe storage.
             */
            hostentstruct = *hostentptr;

            /*
             * Fill in the address structure for socket 2.
             */
            sock2_name.sin_family = hostentstruct.h_addrtype;
            sock2_name.sin_port = htons(atoi(argv[1]));
            sock2_name.sin_addr = * ((struct in_addr *) hostentstruct.h_addr);

            /*
             * Bind name to socket 2.
             */
            retval = bind ( sock_2,
                            (struct sockaddr*)&sock2_name,
                            sizeof sock2_name );
            if (retval)
                    {
                    perror("bind");
                    cleanup(sock_2);
                    }

            /*
             * Select socket to receive message.
             */
            emask = wmask = 0;
            rmask = (1<<sock_2);  /* set read mask */
            timeout.tv_sec = 30;
            timeout.tv_usec = 0;

            retval = select( 32, &rmask, &wmask, &emask, &timeout );
            switch (retval)
            {
              case -1:
                    {
                    perror("select");
                    cleanup(sock_2);
                    }
              case 0:
                    {
                    printf("Select timed out with status 0.\n");
                    cleanup(sock_2);
                    }
              default:
                    if ((rmask & (1<<sock_2)) == 0)
                            {
                            printf("Select not reading on sock_2.\n");
                            cleanup(sock_2);
                            }
              } /*switch*/

            /*
             * Recvfrom buffer - from sock1 on sock2.
             */

            buflen = sizeof(recvbuf);
            fromlen = sizeof(sock1_name);
            flag = 0;          /* flag may be MSG_OOB and/or MSG_PEEK */

            retval = recvfrom( sock_2,
                               recvbuf,
                               buflen,
                               flag,
                               (struct sockaddr*)&sock1_name,
                               &fromlen);
            if (retval == -1)
                    perror("recvfrom");
                 else
                    printf (" %s\n", recvbuf);

            /*
             * Call cleanup to shut down and close socket.
             */

             cleanup(sock_2);

      } /* end main */

Previous | Next | Contents