The following options are available at the socket level:
If you include the UCX$INETDEF definition file, you can use the options listed in Tables 6-3, 6-4, and 6-5.
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. |
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. |
IP Option | Description |
---|---|
UCX$C_IP_TTL | Time to live for a datagram |
UCX$C_IP_TOS | Type of service (1-byte value) |
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.
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.
0 Successful completion. --1 Error; errno is set to indicate the error.
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.
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.
#include <socket.h>
short int vaxc$get_sdc (int s);
s
A socket descriptor.
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.
0 Indicates that s is not an open socket descriptor. x The SDC number.
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.
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 |
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.
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:
$ CC /PREFIX=ALL UCX$TCP_SERVER_QIO.C $ LINK UCX$TCP_SERVER_QIO
$ CXX /PREFIX=ALL/DEFINE=VMS UCX$TCP_SERVER_QIO.C $ LINK UCX$TCP_SERVER_QIO
SYS$LIBRARY:UCX$IPC.OLB/LIB SYS$SHARE:VAXCRTL.EXE/SHARE
$ 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:
Depending on your compiler, you can compile and link this program in any of the following ways:
$ CC /PREFIX=ALL UCX$UDP_SERVER_IPC.C $ LINK UCX$UDP_SERVER_IPC
$ CXX /PREFIX=ALL/DEFINE=VMS UCX$UDP_SERVER_IPC.C $ LINK UCX$UDP_SERVER_IPC
SYS$LIBRARY:UCX$IPC.OLB/LIB SYS$SHARE:VAXCRTL.EXE/SHARE
$ 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 */