TCP Socket Library The Socket Library is a communication package with which programs can exchange messages and data with each other over ethernet via TCP/IP sockets. With this package both VMS and UNIX programs can communicate with each other and so can microprocessors running VxWorks, and PC's with TCP/IP drivers. If the communicating programs are running on the same computer, the same protocol is used although no actual ethernet transmission occurs. (The UNIX version of the Socket Library was written for the NRAO 12m telescope operating system by Jeff Hagen. The library was ported to VMS and DOS by Bill Peters.) Each program is assigned one "mailbox". (These are NOT the same as VMS mailboxes.) Each mailbox has a name. The name of the host which runs the program using this mailbox is defined in a mailbox definition file. This file also associates a TCP port number with the mailbox. (The port number is an arbitrary number > 1024 and < 65535 which must be unique for the host.) Each host must have a copy of this file. The standard location for this file is SYS$MANAGER:MAILBOXDEFS on VMS, c:\mailboxd on DOS, and /etc/mailboxdefs on UNIX. This can be overridden by setting the "environment variable", MAILBOXDEFS, to the name of the file. (Under VMS, an environment variable is a DCL symbol or a logical name; under DOS, use SET MAILBOXDEFS = ...; and under UNIX, setenv MAILBOXDEFS ...). The following C routines are available to programs using the Socket Library. The calling program should also #include . struct BOUND *sock_bind(char *mbname) - binds this program to the mailbox "mbname" so that it will receive messages sent to this mailbox. This mailbox name must be in the MAILBOXDEFS file and its host name should be that of the host running the program. This should only be called once. If the return value is NULL, the call failed (an error message is printed). Under the current implementation, there is no further need for the return value. No other program currently running on the host may be "bound" to this mailbox. struct SOCK *sock_connect(char *mbname) - Use this call to prepare for sending messages to mailbox "mbname". Returns a "handle" to be passed to other routines in the library such as sock_send(). The connection is not established until the first message is sent. This should be done once for each "mbname". (This is NOT necessary if the program is simply replying to an unsolicited message received.) Returns NULL if the call failed (an error message is printed). int sock_send(struct SOCK *s, char *message) - Send to socket "s" the (NUL terminated) string contained in "message". "s" is the handle returned by sock_connect(), sock_find(), or last_msg(). Returns 1 on success and 0 on failure. Success does not necessarily mean that the message was received, only that it was sent. A failure can result if the receiving program is not running. When a failure occurs, the socket is closed and another connection will automatically be attempted the next time sock_send() is called. (Operating systems typically queue messages for about 30 seconds before rejecting them as undeliverable, so the calling program may not get a "failure" until it attempts a second message.) int sock_write(struct SOCK *s, char *message, int len ) - Same as sock_send, but sends arbitrary data. "len" is the length in bytes of the data in "message" to be sent. int sock_sel(char *message, int *len, int *p, int n, int tim, int rd_in) - Waits for a message from socket(s) or other sources of input. "message" is the buffer where a socket message will be put. "len" is the length in bytes of the message (returned); "p" is an array of additional file descriptors that sock_sel will wait on (for example, an RS 232 port). "n" is the number of descriptors in "p"; "tim" is a timeout in seconds. If 0, sock_sel() will wait indefinitely. If < 0, sock_sel() will immediately return the number of sockets and/or file descriptors with a message waiting for delivery (and the message is NOT read). "rd_in" non-zero means that sock_sel will also read messages from the "standard input" file descriptor, stdin. sock_sel returns: -1 if a timeout. -2 if an error -3 if interrupted by a signal and if "tim" >= 0: the file descriptor from "p" that is ready (no "message" is read). or 0 if "standard input" was the source of "message". or the file descriptor of the socket that filled in message. IMPORTANT: A file descriptor is NOT the same as a socket "handle". To reply to a message, first call last_msg() to get the handle of the socket that filled in the message, then call sock_send() (for example). int sock_ssel(struct SOCK *ss[], int ns, char *message, int *len, int *p, int n, int tim, int rd_in) - Same as sock_sel() except that it will NOT wait for sockets whose handles are given in array "ss". "ns" is the number of handles in "ss". struct SOCK *last_msg(void) - Return the handle of the last socket that sock_sel() or sock_ssel() read. int sock_close(char *name) - Close socket "name". If "name" is NULL, close all sockets. char *sock_name(struct SOCK *s) - Return a pointer to the name of the socket corresponding to the socket handle "s". struct SOCK *sock_find(char *mbname) - Return the handle of the socket named "mbname", or NULL if there have been no messages to/from that socket. int sock_only(struct SOCK *s, char *message, int tim ) - Waits for a message only from the socket with the handle, "s". The message is placed in "message". "tim" is a timeout: > 0 means the number of seconds to wait. = 0 means there is no time out < 0 means use the same >0 timeout previously specified. Returns the file descriptor of the socket upon success else: -1 if a timeout. -2 if an error -3 if interrupted by a signal int sock_fd(struct SOCK *s) - Returns the file descriptor for the socket with the handle "s". int sock_intr(int flag) - Change the response of sock_sel() and sock_ssel() when the call to select() aborts due to a signal being delivered (UNIX version only): "flag" is zero --> ignore and call select() again. (Default.) "flag" is non-zero --> return (-3) to caller. int sock_bufct(int bufct); - Set the maximum size (bytes) of all socket messages received to "bufct". (Default: 4096.) If a message larger than this is received, it is assumed that the byte count is not a byte count after all but instead is data. The socket is closed and the message is discarded.