C$SOCKET

This routine can be used to communicate with other processes on remote or local hosts. This provides an interface to inter-process communication via sockets.

Usage

CALL "C$SOCKET" 
    USING OP-CODE, parameters

Parameters

OP-CODE Numeric parameter Specifies the operation to perform. These are defined in the description below.
Parameters Various types defined in socket.def.

The remaining parameters vary depending on the operation selected. They provide information and hold results for the operations specified.

Description

All parameters passed to C$SOCKET are passed BY REFERENCE. The C$SOCKET routine provides any necessary conversions. Numeric arguments passed to this routine must be declared as COMP 5.

Note: If a COBOL thread calls one of these operations, all threads are blocked until the operation is finished and control is returned to the COBOL program.

AGS-CREATE-SERVER (op-code 1)

This operation creates a server-side socket. It must be called once at the beginning of any service you create. If the call is successful, the value in RETURN-CODE should be moved to a data item that is USAGE HANDLE. This data item is then passed as the socket handle to AGS-ACCEPT or AGS-NEXT-READ. This socket handle is not available for read or write operations. You can use the GIVING phrase instead of MOVE to store the value in a data item. If the call fails, RETURN-CODE is NULL. This operation has the following parameters:

port-number    a numeric value specifying the port on which the socket is created. All clients must use the same port number to connect to this server.
server-name a PIC X(n) data item indicating the network interface address to which the server will be attached. Optional.
numeric a numeric data item holding a non-zero value when server-name is a numeric IP address. Optional.

AGS-ACCEPT (op-code 2)

This operation waits for a connection from a client. It blocks other calls while waiting, and returns only after a client has attempted to connect. If a client successfully connects, the value in RETURN-CODE is a socket handle that may be used to communicate with the client using AGS-WRITE and AGS-READ. This operation is called once if the server is a single-client server. In that case, once the client has connected it is safe to close the original server socket (created in AGS-CREATE-SERVER) using AGS-CLOSE, and use only the socket handle returned by this operation. This operation has a single parameter:

socket-handle     this is returned by a call from AGS-CREATE-SERVER.

AGS-CREATE-CLIENT (op-code 3)

This operation attempts to connect to a server. It waits only a short time before giving up, so the server should be running before the client makes this call. (The length of time is dependent on the underlying socket layer.) If it is successful, the value in RETURN-CODE is a socket handle that can be used to communicate with the server using AGS-WRITE and AGS-READ. The socket handle should be moved to a data item of USAGE HANDLE. This operation takes three parameters:

port-number     a numeric value specifying the port on which the socket is created.
server-name    a PIC X(n) data item that holds the machine name of the server. Optional.
numeric a numeric data item holding a non-zero value when the server-name is a numeric IP address. Optional.

AGS-CLOSE (op-code 4)

This operation closes a socket handle. After closing a socket handle, it should no longer be referenced. This operation takes a single parameter:

socket-handle     this indicates which socket to close.

AGS-WRITE (op-code 5)

This operation writes data to a socket, either from the client to the server, or from the server to the client. With this operation, data is actually written:

  • when AGS-READ is attempted on that socket,
  • when you are querying for any available sockets to read using AGS-READ or AGS-NEXT-READ, or
  • when you call AGS-FLUSH.

The value in RETURN-CODE is the number of bytes written. If this is different than the length parameter, an error has occurred.

Note: It is up to you to make sure that the server is writing when the client is reading, and vice versa. If both attempt to read at the same time, a deadlock will result.

This operation takes three parameters:

socket-handle    a valid socket handle returned from AGS-ACCEPT, AGS-CREATE-CLIENT, or AGS-NEXT-READ.
buffer indicates a buffer to write. It can be of any format, including a group item.

Be careful when sending numeric data across the network because some machines use different byte ordering than others and native numeric data can appear swapped on different machines. COMP-4 data is in the order that most network servers expect for binary data. If you are communicating with a non-COBOL client or server, you should use COMP-4 data of the correct size for the machine in question. If your client and server are both COBOL, you can use standard COBOL types.

length the number of bytes to write. If the buffer passed is smaller than the value of this parameter, an error will result.

AGS-READ (op-code 6)

This operation reads data from a socket. It blocks other calls until all the data requested is actually read, or an error occurs. The value returned in RETURN-CODE is the number of bytes actually read. If this is different than the length parameter, an error occurred. If the socket is closed before the entire buffer is filled, C$SOCKET will return the number of bytes read to that point, which will be less than the amount requested. The next time AGS-READ is called, C$SOCKET will return -1 to signify that the socket is closed. This operation takes four parameters:

socket-handle    a valid socket handle returned from AGS-ACCEPT, AGS-CREATE-CLIENT, or AGS-NEXT-READ.
buffer indicates a buffer to read. It can be of any format, including a group item. (The same cautions about byte order described in AGS-WRITE apply here.)
length the number of bytes to read. If the buffer passed is smaller than the value of this parameter, an error will result. If length = 0, then the return value is the number of bytes available to be read on the socket. In other words, after calling AGS-READ with a length of 0, you can call AGS-READ again with a length equal to the previous return value and be guaranteed not to block. If length is negative, the data is moved to the buffer, but it is also left in the socket so that a future call to AGS-READ can read it again. In this case, the number of bytes transferred to the buffer is the absolute value of length.
timeval a number, measured in milliseconds, that determines how long to execute this operation. If the specified time-out period passes, buffer will contain as much data as is available, and the return value will be the number of bytes read. This will probably be less than the number of bytes desired. This allows COBOL programs to wait for data that may not come.

AGS-FLUSH (op-code 7)

This operation flushes any data in the socket, sending any data that has been written, and checking for data to be read. The data to be read is stored in an internal buffer, awaiting a call to AGS-READ. This operation returns no value. This operation takes a single parameter:

socket-handle    this indicates which socket handle to flush.

AGS-EMPTY (op-code 8)

This operation is similar to AGS-READ, except that the number of bytes is thrown away, rather than being stored. This operation takes two parameters:

socket-handle    a valid socket handle returned from AGS-ACCEPT, AGS-CREATE-CLIENT, or AGS-NEXT-READ.
length the number of bytes to throw away. Setting this parameter means that AGS-EMPTY will not complete until that many bytes are available on the socket to throw away.

AGS-GETHOSTNAME (op-code 9)

This operation allows the COBOL program to get the name of the host machine on which the COBOL program is executing. The return value is "0" on success, and "-1" on error. This operation takes a single parameter:

hostname    this parameter should be a PIC X(n) parameter. The name of the host machine is stored in this data item.

AGS-LAST-ERROR (op-code 10)

This operation allows the COBOL program to determine the last error on a socket. This information is only meaningful when an error has occurred. It is useful if one of the operations that returns a socket handle returns an error instead. The value stored in RETURN-CODE is the error number. The error numbers are listed by name in socket.def. To interpret these error codes, see third-party documentation about sockets. This operation takes a single parameter:

socket-handle    a valid socket handle returned from AGS-ACCEPT, AGS-CREATE-CLIENT, or AGS-NEXT-READ, or a NULL socket handle.

AGS-NEXT-READ (op-code 11)

This operation allows you to create multi-client servers. It waits until data is ready to be read from one of the sockets your server has created. Note that this operation only returns information about sockets created as children of the server socket passed (meaning that it only waits for sockets that were ACCEPTed from that socket) and ignores all other sockets. It automatically accepts new client connections from AGS-CREATE-CLIENT, and returns the corresponding socket handle as one that can be read. The value in RETURN-CODE is a socket handle returned from AGS-ACCEPT, AGS-CREATE-CLIENT, or AGS-NEXT-READ, 0 to signify that the timeval has elapsed, or -1 to signify an error. (The socket handle returned from this operation may be from a new client which has connected and sent data. If your program has not yet recognized this as a valid socket, the value may be unfamiliar to you.) This operation takes two parameters:

server-socket-handle the socket handle returned by AGS-CREATE-SERVER.
timeval a number, measured in milliseconds, that determines how long to execute this operation. The first time you call AGS-NEXT-READ, timeval determines the length of time the operation executes. All subsequent invocations of this operation are handled in one of two ways:
  1. If there is a socket handle that has already been determined to have data available, that socket handle is returned immediately regardless of the value of timeval.
  2. If all sockets have been processed, then the setting of timeval determines how long the routine will execute, just as in the initial call. Any sockets that receive data during that time will store the data until AGS-READ or AGS-EMPTY is called with that socket as an argument. Any future calls to AGS-NEXT-READ will return those socket handles.

If timeval is set to 0, all the sockets are checked and the operation returns immediately. If no sockets have data, the routine returns 0. Otherwise the return value will be a socket that has data. If timeval is set to the default of -1, the operation waits until a socket which can be read is available (potentially forever). If all your server does is service clients, then you should always pass the value of -1 as the timeval. The only reason to pass a timeval that is not -1 is if your server wants to perform other work while it is not busy servicing clients.

AGS-REMOTE-NAME (op-code 12)

This operation returns the name of a remote machine. It takes two parameters:

socket-handle    a valid socket handle returned from AGS-ACCEPT, AGS-CREATE-CLIENT, or AGS-NEXT-READ.
remote-name a PIC X(n) data item that is filled with the name of the remote machine.

AGS-REMOTE-ADDR (op-code 13)

This operation returns the IP address of a remote machine. It takes two parameters:

socket-handle    a valid socket handle returned from AGS-ACCEPT, AGS-CREATE-CLIENT, or AGS-NEXT-READ.
remote-addr a PIC X(n) data item that is filled with the IP address of the remote machine.

AGS-READ-LINE (op-code 14)

This operation reads a line of data from a socket. A line is defined as a block of text terminated by either a NewLine or Carriage-Return / NewLine (NL or CRNL). The NL or CRNL is stripped from the data before it is returned, and the return value is the number of bytes read, not counting the NL or CRNL. This operation blocks other calls until all the data requested is actually read, or an error occurs. This operation takes four parameters:

socket-handle    a valid socket handle returned from AGS-ACCEPT, AGS-CREATE-CLIENT, or AGS-NEXT-READ.
buffer indicates a buffer to read. It can be of any format, including a group item. (The same cautions about byte order described in AGS-WRITE apply here.)
length the number of bytes to read. If the buffer passed is smaller than the value of this parameter, an error results. If length = 0, then the return value is the number of bytes available to be read on the socket. In other words, after calling AGS-READ-LINE with a length of 0, you can call AGS-READ-LINE again with a length equal to the previous return value and be guaranteed not to block. If length is negative, the data is moved to the buffer, but it is also left in the socket so that a future call to AGS-READ-LINE can read it again. In this case, the number of bytes transferred to the buffer is the absolute value of length.
timeval a number, measured in milliseconds, that determines how long to execute this operation. If the specified time-out period passes, buffer will contain as much data as is available, and the return value will be the number of bytes read. This will probably be less than the number of bytes desired. This allows COBOL programs to wait for data that may not come.

AGS-GETHOSTADDR (op-code 15)

This operation code takes a single argument:

host-address    A pic x(15) or larger item. This is the address of the local host in dotted notation (192.15.4.32) when C$SOCKET returns.

AGS-GETSOCKETPORT (op-code 16)

This operation code takes a single argument:

socket-handle    This is a socket handle. The return value is the port being used by that socket, or -1 on error. This is useful when passing 0 as the port number when creating a socket, since a socket is created on some unknown port in that case. This function can then be used to determine the actual port being used.

Example

Three sample programs are provided to illustrate the use of the C$SOCKET routine.

  • sockcli.cbl is a client that connects to a server and sends it data. The server returns the data modified.
  • socksrv1.cbl is a single-client server. This means that it can accommodate a single client. When that client shuts down, the server also halts. If another client subsequently tries to connect to the server, it is ignored.
  • socksrvm.cbl is a multi-client server. Any number of clients can attach to this server. When one client disconnects, the rest continue to be serviced.

Because of limitations in the socksrvm.cbl sample program, the only way to halt the server is to kill it at the operating system level. This is not a general requirement of multi-client servers.