Skip to main content

TCP Client/Server Communication

This page describes how to set up remote communication between InterSystems IRIS® data platform processes using TCP/IP.

Introduction

To create a client-server relationship between systems, you must follow a particular set of conventions:

  • Your systems must be connected with appropriate networking hardware and software, including TCP/IP protocol software.

  • Systems communicate with each other through a TCP port. The processes at both ends of the connection must use the same port number.

  • You specify either the TCP port number, or the devicename of the device that represents it, as the device in InterSystems IRIS OPEN, USE, and CLOSE commands.

Using these conventions, the general procedure of establishing a TCP binding connection is:

  1. The server process issues an OPEN command to a TCP device.

  2. The server process issues a USE command, followed by a READ command, awaiting input from the client process. The server must be listening before a client can establish a connection. The initial READ command completes when the client has opened the connection and sent some data. You can include the A mode parameter in the OPEN command to make the initial READ complete as soon as the server accepts the connection.

  3. The client process issues an OPEN command that specifies the TCP device to which it is connecting.

  4. The client process issues a USE command followed by a WRITE command to complete the connection. InterSystems IRIS copies all characters in the WRITE command(s) to a buffer. It does not write them to the network until you issue a WRITE ! or WRITE # command to flush the buffer.

  5. After the server has read the characters that the client sent in its first WRITE command, both sides can continue to issue READ and WRITE commands. There is no further restriction on the order of these commands to the same port.

  6. Either side can initiate the closing of a connection with the CLOSE or HALT command. Closing the client side first is preferable. If the server needs to disconnect so that it can accept a connection from another client process, it can instead issue a WRITE *-2 command.

Note:

This procedure assumes that both the client and server are InterSystems IRIS processes (though either process can be a non-InterSystems IRIS process).

The following sections detail how to use InterSystems IRIS I/O commands to create a TCP binding between client and server processes.

OPEN Command for TCP Devices

Both server and client processes use the ObjectScript OPEN command to initiate a connection. The server completes the connection by issuing a READ command, which receives the client OPEN command and first data transmission.

Note:

If you issue an OPEN command on a TCP device that has already been opened, this second OPEN command is treated as a USE command. That is, the hostname and port parameters are ignored (retaining the first OPEN command values) and the mode and terminators parameters are updated.

Using the OPEN Command

The OPEN command reserves a TCP binding device for your use. The syntax is:

OPEN devicename:parameters:timeout:mnespace

where:

devicename

A string of the form |TCP| followed by some number of numeric digits. The numeric portion of the device name is called the device identifier. If the port number is not specified in the OPEN parameters, this device identifier must be a unique five-digit TCP port number. If the port number is specified in the OPEN parameters (which is the preferred practice), this device identifier can be any unique number (up to a maximum of 2147483647), so long as all the TCP device names used by a single job are distinct.

parameters

Optional — A series of one or more device parameters, enclosed by parentheses and separated by colons (:). If a parameter is omitted, specify the colon separator for the missing parameter. (For a server-side OPEN the first parameter is always omitted.) The specific parameters are described below.

If you specify only the first parameter (hostname), you can omit the parentheses. For example, the client-side open: OPEN "|TCP|7000":"127.0.0.1":10. If you specify no parameters, you can omit the parentheses, but you must retain the colon as a separator character. For example, the server-side open: OPEN "|TCP|7000"::10.

timeout

Optional — Maximum number of seconds InterSystems IRIS attempts to open the TCP device. If it does not succeed within this interval, it sets $TEST to 0 and returns control to the process. If it succeeds, it sets $TEST to 1. Including a timeout in OPEN commands from the client prevents the client system from hanging if it tries to open a connection while the server is busy with another client. The server can have only one connection open at a time.

mnespace

Optional — Supported as it is for all ObjectScript OPEN commands. There is no predefined mnemonic space for TCP bindings.

If you omit an OPEN argument, you can indicate its absence by specifying the colon separator.

The timeout argument, though optional, is strongly recommended because the success or failure of OPEN is indicated by the value of the $TEST special variable, and $TEST is only set if timeout is specified. $TEST is set to 1 if the open attempt succeeds before the timeout expires; if the timeout expires, $TEST is set to 0.

If a TCP connection attempt fails on Windows systems, the TCP connection error is written to the InterSystems IRIS system error log (see InterSystems IRIS System Error Log), for example, error code 10061 = WSAECONNREFUSED.

The following is an example of a client-side OPEN, where 7000 is the port number and "127.0.0.1" is the parameters argument (the hostname, specified as an IPv4 address):

  SET dev="|TCP|7000"
  OPEN dev:("127.0.0.1":7000)

hostname Parameter

The hostname parameter is required for a client-side OPEN. The client-side parameters argument may be just the hostname, or the hostname followed by other colon-separated parameters. If you specify just the hostname parameter, you can omit the parameters parentheses.

The server-side parameters argument omits the hostname.

The hostname can be either the name of an IP host (from the local system’s database of remote hosts) or an IP address in either IPv4 or IPv6 protocol format. Because these protocols are incompatible, both the server and the client must use the same Internet protocol or the transmission will fail.

An IPv4 address has the following format. n is a decimal integer in the range 0 through 255:

n.n.n.n

An IPv6 address has the following full format. h is a hexadecimal number with four hexadecimal digits:

h:h:h:h:h:h:h:h

Commonly, IPv6 addresses are abbreviated by eliminating leading zeros and replacing consecutive sections of zeros with a double colon (::); only one double colon may be used in an IPv6 address. By using IPv4 abbreviation rules, you can specify the IPv6 loopback address as "::1" (meaning that the first seven consecutive h sections all have the value 0000, and the leading zeros from the eighth section are eliminated).

You can use the OPEN keyword /USEIPV6 to specify which protocol to use. Further details on IPv4 and IPv6 formats can be found in Use of IPv6 Addressing.

Supported Parameters

The parameters argument can be in either of the following formats:

hostname
(hostname{:port{:mode{:terminators{:ibufsiz{:obufsiz{:queuesize{:keepalivetime}}}}}}})

The parameters within the parameters argument are as follows:

hostname

Optional — Either the name of an IP host, an IP address in IPv4 protocol format, or an IP address in IPv6 protocol format. Specified as a quoted string. A hostname is required for a client-side OPEN; omitted (represented by a placeholder colon) for a server-side OPEN.

port

Optional — If present, this is the TCP port number to use for the connection. If this port number is null or omitted, then the port number is derived from the numeric portion of the devicename. This parameter can either be a decimal port number or a service name, which is submitted to the local system’s TCP service name resolver.

mode

Optional — A string of letter code characters enclosed in quotes. Letter codes may be specified in any order; because InterSystems IRIS executes them in left-to-right order, interactions between letter codes may dictate a preferred order in some cases. The default is packet mode. A mode string can consist of one or more of the following letter codes:

  • A — Accept mode. If A is on, the initial read on the server terminates with a zero-length string as soon as the connection from the client job is accepted. If A is off, the read blocks until the timeout is reached, or until data is available, whichever occurs first.

  • C — See Carriage Return Mode below.

  • D — See Monitoring for Disconnect Mode below.

  • E — See Escape Sequence Processing Mode below.

  • G — Causes the port parameter to be interpreted as the socket descriptor of an already opened data socket.

  • M — Standard InterSystems IRIS device in stream mode. This mode is a shorthand for invoking the PSTE set of options. It yields a device that acts like a standard InterSystems IRIS device that can be used to pass arbitrary lines of data in both directions. You turn on stream mode so that you can send or receive any arbitrary sequence of strings, without overrunning the buffers. Line feeds are added to output and stripped from input. READ commands block until one of the following occurs: a terminator character is seen, the timeout is reached, or the read length specified has been filled.

  • P — Pad output with record terminator characters. When this mode is set, WRITE ! sends LF (line feed) and WRITE # sends FF (form feed), in addition to flushing the write buffer. The WRITE *-3 command can be used to initiate the sending of buffered data without inserting any characters into the data stream. Note that WRITE *-3 just flushes the write buffer without sending any terminator character, and thus does not signal the recipient program that the data is complete. WRITE *-3 is more commonly used in Wait (W) mode, which does not require a terminator.

  • Q — See Send Immediate Mode below.

  • S — See Stream Mode below.

  • T — Standard terminators on input. When this is set, the CR, LF, and FF control characters function as read terminators.

  • W — Wait mode. In this mode, WRITE ! and WRITE # commands will not cause a TCP device to flush the network output buffers. Wait mode causes a TCP device to wait until the next WRITE *-3 command to flush the buffers and transmit the data.

terminators

Optional — A list of up to eight user terminator characters that will terminate reads on the TCP binding device. If you specify both T mode and terminators at the same time, T mode is ignored.

ibufsiz

Optional Input buffer size. Internally, characters that have been read from the network but not yet delivered to the InterSystems IRIS program are buffered in a data area that can hold ibufsiz bytes.

obufsiz

OptionalOutput buffer size. The maximum amount of data the TCP device can buffer between successive SEND operations. A SEND operation means to send the buffered data out to the network. WRITE !, WRITE #, and WRITE *-3 commands can generate SEND operations.

When S mode is specified, SEND operations are generated automatically to send the contents of the output buffer whenever it gets too full. When done creating a message, however, the programmer must still use one of the SEND operations to make sure the message is sent.

When S mode is not specified, if a WRITE operation would place enough data in the buffer to exceed the output buffer size, then a <WRITE> error occurs. Note that attempting to write a string that is in itself longer than the output buffer size always fails.

queuesize

Optional — An integer that specifies how many client jobs can queue for a connection to the server. Used for server-side OPEN only. The default is 5. The maximum value depends on the TCP implementation, but cannot exceed 1000.

keepalivetime

Optional — (Windows, AIX, and Linux only) Allows you to set a keepalive timer for this device that is different than the system default. Specify an integer number of seconds to keep alive the TCP connection. Valid values range from 30 to 432000. (432000 seconds is 5 days.) A value less than 30 defaults to 30. If omitted or set to 0, the system-wide default keepalive timer is used. See the /KEEPALIVE keyword option for further details.

The keepalive timer does not necessarily start timing when the TCP device is opened. It typically begins timing when the connection has been established. That is, when the initial read-for-connect has completed successfully.

Packet Mode

Packet mode is the default if no mode is specified. If stream mode is disabled, the mode defaults to packet mode.

In packet mode READ commands complete as soon as there is some data to return. Packet mode allows you to build an entire TCP segment in the output buffer, and then send it all at one time by issuing a WRITE *-3 or WRITE ! command.

If you issue WRITE *-1 to initiate a TCP SEND operation when there are no characters to be sent, you receive a <WRITE> error. If you issue WRITE of an empty string, you receive a <COMMAND> error.

The maximum size of the string you can send in packet mode is 1024 characters. If you exceed this limit without flushing the buffer, you receive a <WRITE> error.

Because TCP/IP ignores records with a length of 0, you receive a <WRITE> error if you flush the write buffer when there are no characters in it.

A WRITE command from server to client before the server has received a connection request produces a <WRITE> error on the server.

Carriage Return Mode (C mode)

This mode modifies processing of carriage returns on input and output.

On Output, WRITE ! generates CR LF and WRITE # generates CR FF.

On input, with T mode enabled, the server tries to record an adjacent CR and LF or an adjacent CR and FF as a single terminator in $ZB. CR and LF are processed as separate terminators if they do not arrive within a short interval of each other. By default, the interval is 1 second.

Monitoring for Disconnect Mode (D mode)

This mode turns on or off asynchronous disconnect monitoring. This mode is activated by specifying the “D” mode character, or the /POLL or /POLLDISCON keyword parameter. When you specify +D, TCP disconnect monitoring is activated; when you specify –D, TCP disconnect monitoring is deactivated.

While activated, InterSystems IRIS polls the TCP connection roughly every 60 seconds. When it detects a disconnect, InterSystems IRIS issues a <DISCONNECT> error. Disconnect detection does not occur in idle jobs, such as a job suspended by a HANG command or a job waiting on a READ operation. InterSystems IRIS suspends all disconnect monitoring during a rollback operation to prevent a <DISCONNECT> error being issued. InterSystems IRIS resumes disconnect monitoring once the rollback concludes. This suspension applies both to a current TCP device with disconnect monitoring activated, and to a current device without disconnect monitoring that is connected to a TCP device with disconnect monitoring activated.

You can also check for TCP disconnect by using the Connected()Opens in a new tab method of the %SYSTEM.INetInfoOpens in a new tab class.

Escape Sequencing Processing Mode (E mode)

When the E mode is set, escape sequences in the input stream are parsed and placed into the $ZB special variable. Escape sequences must be 15 characters or less and must match the following syntax:

esc_seq::=type1 | type2

where:

type1 ::= '['['0':'?']*['':'/']*{'@':DEL}   
type2 ::= [';'|'?'|'O']['':'/']*{'0':DEL}

The syntactic symbols used here mean:

Symbol Description
: x:y means a specified range of characters from x through y in the ASCII sequence.
| x|y means specify either x or y.
[ ] Specify zero or one members of the specified set.
[ ]* Specify zero, one, or more members of the specified set.
{ } Specify exactly one member of the specified set.

When InterSystems IRIS sees an ESCAPE, it waits up to 1 second for the rest of the escape sequence to arrive. If the escape sequence does not match this syntax, or if it is longer than 15 characters, or if a valid escape sequence does not arrive within 1 second, InterSystems IRIS places the partial escape sequence in $ZB and sets the BADESC bit (256) in $ZA.

Send Immediate Mode (Q mode)

In send immediate mode, each WRITE command is output as its own packet. If you are not using send immediate mode, you must either include a terminator or issue the command WRITE *–3 to output a packet.

This mode is entered by specifying the “Q” mode character, or the /SENDIMMEDIATE (or /SEN) keyword parameter. To turn this option off, specify either of the following:

   USE TCPDEVICE:(/SEN=0)
   USE TCPDEVICE:(::"-Q")

To turn this option back on, specify either of the following:

   USE TCPDEVICE:(/SEN=1)
   USE TCPDEVICE:(::"+Q")

Send Immediate Mode, which creates one packet per write, is used in combination with /NODELAY mode, which immediately sends each packet as it is created. When both are on, the speed of transmission of a single burst of data is maximized. This is useful when timely delivery of each unit of data is critical, for example, in transmitting mouse movements. When both are off, a packet may contain multiple writes, and a transmission may contain multiple packets. This reduces network traffic and improves overall performance. The default for Send Immediate Mode is off. The default for /NODELAY mode is on.

Stream Mode (S mode)

In stream mode, InterSystems IRIS does not attempt to preserve TCP message boundaries in the data stream. On sending, if the data does not fit in the message buffer, InterSystems IRIS flushes the buffer before placing the data in it.

On receiving, data up to the maximum string length can be received. All reads wait for the full timeout for terminators to be reached or for the buffer to become full. When this mode is disabled (the default), you are in packet mode.

Jobbed processes that inherit TCP devices are automatically set to Stream format. You can reset the format with the USE command.

Buffer Sizes

The ibufsiz and obufsiz parameters for TCP devices specify the sizes of the internal InterSystems IRIS buffers for TCP input and output. They can take values between 1KB and 1MB on all supported platforms. However, operating system platforms may use different sizes for their own input and output buffers. If the operating system platform buffer is smaller than the InterSystems IRIS buffer (for example, 64KB vs 1MB), performance may be affected: a WRITE operation may require several trips to the OS to send the entire InterSystems IRIS buffer; a READ operation may return smaller chunks that are limited by the OS buffer size. For optimal performance, a user should experiment with the current OS to determine which values for ibufsiz and obufsiz produce optimal results.

Server-Side OPEN Command

When the server-side OPEN is processed, it establishes a TCP socket and listens on the socket for incoming connection requests on the appropriate port number. The port number is either specified explicitly in the parameter list, or derived from the numeric portion of the devicename. The OPEN returns immediately after the socket has been set up to listen.

If the OPEN does not succeed, another process may already be listening for connection requests on that port number.

The following example of a server-side OPEN shows a device specification that allows reading and writing of terminated strings up to the maximum string size, and uses maximum length read and write operations to consolidate use of the TCP channel.

   OPEN "|TCP|4":(:4200:"PSTE"::32767:32767)

The parameters argument in this example is as follows: because this is a server-side OPEN, the first parameter (hostname) is omitted. The second parameter explicitly specifies the port number (4200). The third parameter is the mode code characters. The fourth parameter (terminators) is omitted. The fifth parameter is the input buffer size. The sixth parameter is the output buffer size.

In the following example the port number is not specified as a parameter; it is derived from the numeric portion of the devicename. This example opens port 4200 with no specified parameters and a timeout of 10 seconds:

   OPEN "|TCP|4200"::10

A server-side OPEN has default input buffer size (ibufsiz) and output buffer size (obufsiz) parameter values of 1,048,576 bytes (1 MB).

A server-side OPEN supports the optional queuesize parameter, and the optional G mode parameter. These options are not available to a client-side OPEN.

A server-side OPEN supports the optional /CLOSELISTEN keyword parameter. This option is not available to a client-side OPEN.

Client-Side OPEN Command

A client-side OPEN command differs from the server-side OPEN command in only one respect: the first device parameter must specify the host to which you are connecting. To specify the host, you include either a name that the client recognizes as a host, or an Internet address.

The OPEN succeeds as soon as the connection is established. At this point, you can read or write to the TCP device. However, if the server side of the connection is another InterSystems IRIS process, the server does not complete its side of the connection until some data has been sent from the client to the server with the WRITE command. Therefore, you must issue a WRITE command before you issue any READ commands.

For details, see WRITE Command for TCP Devices.

Some examples of client-side OPEN commands are:

   OPEN "|TCP|4":("hal":4200::$CHAR(3,4)):10

This command opens a connection to host hal on port 4200. It specifies no mode string. It specifies two terminators (ASCII $CHAR(3) and $CHAR(4)), and default input and output buffer sizes. It specifies a timeout of 10 seconds.

The following command is the same as the previous one, except that the destination is an explicit IP address in IPv4 format.

   OPEN "|TCP|4":("129.200.3.4":4200::$CHAR(3,4)):10

You can use the OPEN keyword /USEIPV6 to specify which protocol to use. Further details on IPv4 and IPv6 formats can be found in Use of IPv6 Addressing.

The following command connects to time-of-day server on remote host larry and prints the remote host’s time of day in ASCII format on the principal input device. It uses the service name daytime, which the local system resolves to a port number:

   OPEN "|TCP|4":("larry":"daytime":"M")
   USE "|TCP|4" 
   READ x
   USE 0
   WRITE x

The following command sets x to hello:

   OPEN "|TCP|4":("larry":"echo":"M")
   USE "|TCP|4"
   WRITE "hello",!
   READ x

The following command opens a connection to Internet address 128.41.0.73, port number 22101, with a 30-second timeout.

   OPEN "|TCP|22101":"128.41.0.73":30

OPEN and USE Command Keywords for TCP Devices

You can either use positional parameters (as described above) or keyword parameters. The following list describes the keywords for controlling TCP devices with both OPEN and USE commands. There are additional OPEN-only keywords that can only be specified in the OPEN command. All keyword parameters are optional.

/ABSTIMEOUT[=1]

Default: 0

Specifies read timeout behavior. Determines whether TCP should reinitialize the timeout period when data is received. If /ABSTIMEOUT=0 (the default) timeout is reset to its original value each time data is received. If /ABSTIMEOUT or /ABSTIMEOUT=1 the timeout period continues to count down while data is received.

/ACCEPT[=n]

Or:

/ACC[=n]

Default: 0

Corresponds to the A mode parameter character, which specifies that the initial read on the server terminates with a zero length string as soon as the connection from the client job is accepted. /ACCEPT and /ACCEPT=n for nonzero values of n enable A mode. /ACCEPT=n for a zero value of n disables A mode.

/CLOSEFLUSH[=n]

Default: 1

Specifies handling of data remaining in the output buffer when the device is closed. /CLOSEFLUSH and /CLOSEFLUSH=n for nonzero values of n flushes remaining data. /CLOSEFLUSH=n for a zero value of n discards remaining data.

/COMPRESS=str

Default: ""

Specifies the stream data compression type. You can enable a compression type of ZLIB or ZSTD. You can specify /COMPRESS="" to disable compression. /COMPRESS="zlib" is equivalent to /GZIP=1. To compress a string, use %SYSTEM.Util.Compress()Opens in a new tab.

/CRLF[=n]

Default: 0

Corresponds to the C mode parameter character, which modifies processing of carriage returns on input and output. /CRLF and /CRLF=n for nonzero values of n enable C mode. /CRLF=n for a zero value of n disables C mode.

/ESCAPE[=n]

Or:

/ESC[=n]

Default: 0

Corresponds to the E mode parameter character, which specifies that escape sequences in the input stream are parsed and placed into $ZB. /ESCAPE and /ESCAPE=n for nonzero values of n enable E mode. /ESCAPE=n for a zero value of n disables E mode.

/GZIP[=n]

Default: 1

Specifies GZIP-compatible stream data compression. /GZIP or /GZIP=n (for nonzero values of n) enables compression on WRITE and decompression on READ. /GZIP=0 disables compression and decompression. Before issuing /GZIP=0 to disable compression and decompression, check the $ZEOS special variable to make sure that a stream data read is not in progress. /GZIP compression has no effect on I/O translation, such as translation established using /IOTABLE. This is because compression is applied after all other translation (except encryption) and decompression is applied before all other translation (except encryption). For further information on WRITE with compressed data, see WRITE Control Characters.

/IOTABLE[=name]

Or:

/IOT[=name]

Default: If name is not specified, the default I/O translation table for the device is used.

Establishes an I/O translation table for the device.

/KEEPALIVE=n

Default: system default

(Windows, AIX, and Linux only) Allows you to set a keepalive timer for this device that is different than the system default. An integer that specifies the number of seconds to keep alive the TCP connection. Same as the keepalivetime positional parameter. Valid values range from 30 to 432000. (432000 seconds is 5 days.) A value less than 30 defaults to 30. If omitted or set to 0, the system default is used. This setting can be disabled using /NOKEEPALIVE; once disabled, it cannot be re-enabled until this TCP device is closed.

/NODELAY=n

Default: 1

Specifies whether packets should be bundled or sent individually. If /NODELAY=1 (the default) each packet is immediately transmitted. If /NODELAY=0 the TCP driver bundles packages together using an optimization algorithm. This can cause a slight transmission delay for an individual packet, but by reducing network traffic it can improve overall performance. /NODELAY has no corresponding mode parameter character. Use of /NODELAY should be coordinated with use of /SENDIMMEDIATE.

/NOKEEPALIVE

If specified, the system-wide TCP keepalive timer is disabled for this device. InterSystems IRIS enables this timer by default when opening any TCP device; issuing the /NOKEEPALIVE option on OPEN or USE overrides this default. If /KEEPALIVE has been used to set a non-default keepalive timer, /NOKEEPALIVE disables that keepalive timer. Once you disable a keepalive timer there is no way to re-enable it until the TCP device is closed. See /KEEPALIVE.

/NOXY[=n]

Default: 0

No $X and $Y processing: /NOXY or /NOXY=n (for nonzero values of n) disables $X and $Y processing. This option can improve performance when device $X/$Y is not used, for example with CSP. It can substantially improve performance of READ and WRITE operations. This option is the default setting for superserver worker jobs. When /NOXY=1, the values of the $X and $Y variables are indeterminate, and margin processing (which depends on $X) is disabled. /NOXY=0 enables $X and $Y processing; this is the default. /TCPNOXY is a deprecated synonym for /NOXY.

/OBCOUNT=n

Default: 16

The number of output buffers to use with /ZEROCOPY. The default number of output buffers is 16. The minimum number of output buffers is 2 and the maximum is 128. The value of n must be power of 2; if a non-power-of-2 value is specified, it is rounded up to a power of 2.

/PAD[=n]

Default: 0

Corresponds to the P mode parameter character, which specifies that output is padded with record terminator characters when WRITE ! (LF terminator) or WRITE # (FF terminator) is executed. /PAD and /PAD=n for nonzero values of n enable P mode. /PAD=n for a zero value of n disables P mode.

/PARAMS=str

Or:

/PAR=str

No default. Corresponds to the mode positional parameter. (It provides a way to specify a mode string in a position-independent way.)

/POLL[=n]

Or:

/POLLDISCON[=n]

Corresponds to the D mode parameter character, which specifies asynchronous monitoring for disconnect. /POLL or /POLL=1 corresponds to +D. /POLL=0 corresponds to -D.

/PSTE[=n]

Default: 0

Corresponds to the M mode parameter character, which is a shorthand way to specify the P, S, T and E mode parameter characters. /PSTE and /PSTE=n for nonzero values of n enable P, S, T and E modes. /PSTE=n for a zero value of n disables these modes.

/SENDIMMEDIATE[=n]

Or:

/SEN[=n]

Default: 0

Corresponds to the Q mode parameter character, which specifies Send Immediate Mode.

/SSL="cfg[|pw] [|DNShost]"

Or:

/TLS="cfg[|pw] [|DNShost]"

No default.

From a client, specifies that the device attempts to negotiate an SSL/TLS-secured connection according to the client’s specified configuration and server requirements. When securing a socket as a server, specifies that the server requires a SSL/TLS-secured connection according to the server’s specified configuration and any client requirements.

The value of the /SSL or /TLS keyword parameter is a quoted string. This string can have one, two, or three components, separated by the '|' character:

  • cfg specifies the name of the configuration for the connection or socket. pw specifies the optional private key file password. DNShost specifies the fully qualified DNS hostname of a specific server, for use with the Server Name Indication (SNI) TLS extension.

    This configuration name is used only the first time I/O is performed after the OPEN or USE command. Subsequent invocations are ignored. /SSL="" or /TLS="" is ignored. For more information, see InterSystems TLS Guide.

  • pw (optional) is the password for the local private key file. This is intended for interactive applications only, when a user is being prompted to enter the password at run time. It should not be used with a persistently stored password. Use the Security.SSLConfigs.PrivateKeyPassword property for persistent storage.

    IMPORTANT: The ability to include a password when opening a new or securing an existing TCP connection using SSL/TLS is for real-time interactive use only. You should never store a private key password persistently without protecting it. If you need to store such a password, use the PrivateKeyPassword property of the Security.SSLConfigsOpens in a new tab class.

  • DNShost (optional) for SSL clients only, specifies the fully qualified DNS hostname of a specific server (for Server Name Indication). If you omit pw you must specify the placeholder '|' character.

    Server Name Indication (SNI) is a feature that allows the client to submit the hostname it's asking for to the server. This allows a server which handles multiple domains to select one of its multiple certificates to return. The server can select one which will match hostname checking on the client.

The following are examples of valid /TLS keyword parameters:

/TLS="Client"
/TLS="Client|password"
/TLS="Client||www.intersystems.com"
/TLS="Client|password|www.intersystems.com" 
/STREAM[=n]

Or:

/STR[=n]

Default: 0

Corresponds to the S mode parameter character, which specifies a stream mode of handling data that does not preserve TCP message boundaries. /STREAM and /STREAM=n for nonzero values of n enable S mode. /STREAM=n for a zero value of n disables S mode.

/TCPNOXY

Deprecated. A synonym for /NOXY.

/TCPRCVBUF=n

Default: Default receive buffer size

Set receive queue buffer size, in bytes. Can be used to increase the buffer size from the default value to support TCP protocol large windows. Large windows improve performance over links with long latencies or very high bandwidth. For appropriate values, consult your OS/hardware documentation.

/TCPSNDBUF=n

Default: Default send buffer size

Set send queue buffer size, in bytes. Can be used to increase the buffer size from the default value to support TCP protocol large windows. Large windows improve performance over links with long latencies or very high bandwidth. For appropriate values, consult your OS/hardware documentation.

/TERMINATOR=str

Or:

/TER=str

No default.

Corresponds to the terminators positional parameter, which establishes user-defined terminators.

/TMODE[=n]

Or:

/TMO[=n]

Default: 0

Corresponds to the T mode parameter character, which specifies CR, LF, and FF as standard read terminators. /TMODE and /TMODE=n for nonzero values of n enable T mode. /TMODE=n for a zero value of n disables T mode.

/TRANSLATE[=n]

Or:

/TRA[=n]

Default: 1

/TRANSLATE or /TRANSLATE=n for nonzero values of n enable I/O translation for the device. /TRANSLATE=n for a zero value of n disables I/O translation for the device.

/WAIT[=n]

Default: 0

Corresponds to the W mode parameter character, which causes output buffers not to be flushed by the WRITE ! and WRITE # commands. Rather, flushing waits until the next WRITE *-3 command. /WAIT and /WAIT=n for nonzero values of n enable W mode. /WAIT=n for a zero value of n disables W mode.

/WRITETIMEOUT[=n]

Default: –1

Establishes a timeout (in seconds) for TCP write operations. If a write does not complete within n seconds, InterSystems IRIS issues a <TCPWRITE> error. If a <TCPWRITE> error is issued, your application should immediately close the TCP device to prevent data loss. InterSystems IRIS will not attempt a TCP write operation following a <TCPWRITE> error. The minimum n value is system-dependent. If n is smaller than the minimum timeout value for the platform, InterSystems IRIS uses the platform minimum. No n value should be less than 2. The default (-1) indicates no timeout is enforced.

/XYTABLE[=name]

Or:

/XYT[=name]

Default: If name is not specified, the default $X/$Y action table for the device is used.

Establishes a $X/$Y action table for the device. See /NOXY.

/ZEROCOPY[=bool]

Default: 0

If /ZEROCOPY or /ZEROCOPY=1 is specified, enable the ZEROCOPY feature for this TCP device. ZEROCOPY supports multiple output buffers for the TCP device in order to take advantage of MSG_ZEROCOPY on send(); the TCP device cannot re-use the output buffer until the buffer has been acknowledged by notification from the TCP stack. To set the number of output buffers for the TCP device use the /OBCOUNT keyword. If /ZEROCOPY=0 is specified, disable the ZEROCOPY feature for this TCP device. MSG_ZEROCOPY is supported in Linux 4.15 and later. If the operating system does not support MSG_ZEROCOPY, the ZEROCOPY of the TCP device is always disabled.

OPEN-Only Command Keywords for TCP Devices

The following list describes the keywords for controlling TCP devices that can only be specified in the OPEN command. There are additional OPEN/USE keywords that can be specified with either the OPEN or USE command. All keyword parameters are optional.

/BINDTO[=address]

Binds to a specified local address that is used when initiating connection. For client, this is the source address used when opening a TCP/IP connection from InterSystems IRIS. For server, this is the IP address that the InterSystems IRIS process will accept connections on when opening a TCP/IP connection. /BINDTO=address is used to control which network interface the connection will use. /BINDTO or /BINDTO=”“ deletes a previously specified address. If the specified address does not exist, the OPEN command will time out.

/CLOSELISTEN

(Server only) Prevents more than one remote connections to the listening port. If specified, the listen socket is closed after the first connection is accepted. Additional clients attempting to connect will time out on the OPEN command.

/CONNECTIONS=n

Or:

/CON=n

Default: 5

Corresponds to the queuesize positional parameter, which determines how many client jobs can queue for a connection to the server.

/HOSTNAME=str

Or:

/HOS=str

No default.

Corresponds to the hostname positional parameter, which is either the name of an IP host or an IP address in IPv4 or IPv6 address format. You can use the /USEIPV6 keyword to specify which protocol to use. Further details on IPv4 and IPv6 formats can be found in Use of IPv6 Addressing.

/IBUFSIZE=n

Or:

/IBU[=n]

Default: 1024

Corresponds to the ibufsiz positional parameter, which specifies the size of the TCP input buffer that holds data read from the network, but not yet delivered to the application.

/OBUFSIZE=n

Or:

/OBU[=n]

Default: 1024

Corresponds to the obufsiz positional parameter, which specifies the size of the TCP output buffer that contains data that is held between successive "SEND" operations.

/PORT=n

No default.

Corresponds to the port positional parameter, which is either the TCP port number or a service name to use for the connection.

/SOCKET=n

Or:

/SOC=n

No default.

Corresponds to the G mode parameter character, which causes the port positional parameter to be interpreted as the socket descriptor of an already opened data socket. This keyword takes as its value that socket descriptor and is used instead of the /PORT=n keyword. (A socket descriptor is passed to ObjectScript from another programming environment, such as C, using the InterSystems IRIS Call-in or Call-out mechanisms.)

/USEIPV6

No default.

If /USEIPV6 or /USEIPV6=1 is specified, use an IPv6 address for both inbound and outbound connections, overriding the IPV6 system switch. If /USEIPV6=0 is specified, use an IPv4 address for both inbound and outbound connections, overriding the IPv6 system switch.

If /USEIPV6 is not specified, the IPV6 system switch governs behavior. With IPV6 system switch set, an outbound connection tries to connect with an IPv4 address first; if fails it tries to connection with an IPv6 address. For an inbound connection, the TCP device listens to both IPv4 and IPv6 connections. With IPV6 not set, only IPv4 addresses are used for both inbound and outbound connections.

The following example shows a TCP/IP device being opened using keyword syntax:

  SET dev="|TCP|"_123
  SET portnum=57345
  OPEN dev:(/PSTE:/HOSTNAME="128.41.0.73":/PORT=portnum)

Current TCP Device

You can return the IP address and port number of the current TCP device using the methods of the %SYSTEM.TCPDeviceOpens in a new tab class. You can list these methods using the Help() method, as follows:

  DO $SYSTEM.TCPDevice.Help()

You can display information about a specific method by specifying the method name in Help(), as shown in the following example:

  DO $SYSTEM.TCPDevice.Help("LocalAddr")

USE Command for TCP Devices

The USE command issued from either the client or server lets you prepare to send or receive data using a TCP connection you previously opened. It has the following syntax (colons must be specified as shown):

USE devicename:(::mode:terminators)

Where:

devicename

A string of the form |TCP| followed by some number of numeric digits. The numeric portion of the device name is called the device identifier. If the port number is not specified in the OPEN parameters, this device identifier must be a unique five-digit TCP port number. If the port number is specified in the OPEN parameters (which is the preferred practice), this device identifier can be any unique number, so long as all the TCP device names used by a single job are distinct.

mode

OptionalUSE supports the same mode parameters as OPEN. See OPEN and USE Command Keywords for TCP Devices.

terminators

Optional — A list of up to eight user terminator characters that will terminate reads on the TCP binding device. It does not make sense to specify both T mode and user terminators at the same time, but if you do then T mode is ignored.

The simplest form of USE takes its mode and terminators parameters from the OPEN command, as shown in the following example:

   USE "|TCP|4"

You can replace, add, or delete mode parameters and user terminators after the device has been opened.

To replace the parameters specified in OPEN, specify replacement values in USE. In the following example, the USE command replaces the OPEN mode with PSTE mode and turns off any user terminators:

   USE "|TCP|4":(::"PSTE")

To add to or delete from the mode parameters specified in OPEN, use the + sign to introduce mode parameters that will be turned on, and the - sign to introduce mode parameters that will be turned off. If you do not specify either + or -, the new set of mode parameters replaces the existing mode parameters. In the following example, the USE command turns off Q mode (send immediate) and turns on W mode (wait). It leaves the rest of the mode string unchanged:

   USE "|TCP|4":(::"-Q+W")

In the following example, the USE command leaves the mode string unchanged and specifies a new set of user terminators.

   USE "|TCP|4":(::"+":$CHAR(3,4))

READ Command for TCP Devices

Issue the READ command from either the server or the client to read any characters set by either the client or the server.

The syntax is as follows:

READ var:timeout 
READ *var:timeout
READ var#length:timeout

The timeout argument, though optional, is strongly recommended because the success or failure of the READ is indicated by the value of the $TEST special variable if timeout is specified. $TEST is set to 1 if the read attempt succeeds before the timeout expires; if the timeout expires, $TEST is set to 0.

The timeout argument supports seconds and fractions of a second to 1/100th of a second. For example, 10, 10.5, .5, .05.

For an SSL connection, a job can wait in the first read or first write command if the other party never issues a read or write command after the connection is established. In this circumstance, InterSystems IRIS supports the read timeout for a READ command and write timeout (with /WRITETIMEOUT=n option) for a WRITE command. If there is no read or write timeout specified, then the job will wait until the other party issue a read or write command.

You can determine the number of reads performed by the current TCP connection using the TCPStats()Opens in a new tab method of the %SYSTEM.INetInfoOpens in a new tab class.

READ Modifies $ZA and $ZB

Your application can learn about how the connection and read succeeded by testing the values of $ZA and $ZB.

$ZA and READ Command

$ZA reports the state of the connection. When the 0x1000 bit (4096) is set, this TCP device is functioning in Server mode. When the 0x2000 bit (8192) is set, the device is currently in the Connected state talking to a remote host.

For example, assume that a server-side TCP device is expected to accept a new TCP connection. By looking at $ZA and $TEST after an initial timed read, the InterSystems IRIS program can distinguish among three cases:

$ZA Value $TEST Value Meaning
4096 0 No connection has been accepted.
12288 0 Connection accepted, no data received.
12288 1 Connection accepted and data received.

The following table shows what each bit in $ZA represents.

Decimal Value of $ZA Hexadecimal Value of $ZA Meaning
2 0x2 Read timed out.
4 0x4 I/O error.
256 0x80 Bad escape sequence received.
4096 0x1000 Server mode.
8192 0x2000 Connected.

$ZB and READ Command

$ZB holds the character that terminated the read. This character can be one of the following:

  • A termination character, such as a carriage return

  • The yth character of a fixed-length READ x#y

  • The single character of READ *X

  • An empty string after a timed read expires

  • An escape sequence

Note that if a string is terminated with CR LF, then only the CR is placed in $ZB.

WRITE Command for TCP Devices

The WRITE command sends data to a TCP device from the client or the server after you have established connection with OPEN and USE.

The syntax is as follows:

WRITE x
WRITE ! 
WRITE #

How WRITE Works

WRITE x sends x from the client or server to a buffer after the connection has been established.

WRITE ! and WRITE # do not indicate line and form feed. Instead, they tell InterSystems IRIS to flush any characters that remain in the buffer and send them across the network to the target system.

You can determine the number of writes performed by the current TCP connection using the TCPStats()Opens in a new tab method of the %SYSTEM.INetInfoOpens in a new tab class.

WRITE Modifies $X and $Y

InterSystems IRIS stores the number of characters in the buffer in the $X special variable.

The ASCII characters <return> and <line feed> are not included in this count, as they are not considered part of the record. Flushing the buffer with WRITE ! resets $X to 0, and increases the value of $Y by 1. Flushing the buffer with WRITE # writes the ASCII character <form feed> as a separate record, and resets $Y to 0.

WRITE Command Errors

You can receive a <WRITE> error in any of the following circumstances.

  • If you exceed the maximum string size (1024 characters) without flushing the buffer.

  • If you flush the write buffer when there are no characters in it (TCP/IP ignores records of 0 length).

  • If you send a WRITE command from the server to the client before the server receives a connection request from client. (InterSystems IRIS produces the <WRITE> error on the server.)

WRITE Control Commands

The InterSystems IRIS TCP binding device supports a series of control commands with the WRITE *-n syntax.

Syntax Description
WRITE *-2 On a server-mode session that is currently connected to a client, this command disconnects from the session. To accept a new session, you then execute a new READ command on the device.
WRITE *-3 Sends any buffered output out the TCP connection; that is, executes a TCP SEND operation on the data in the output buffer. If the data is compressed (/GZIP) stream data, *-3 sends the data without marking the compression endpoint. Resets $X to 0. Increments $Y by 1. If there is no buffered output, this command does nothing.
WRITE *-99 Sends compressed (/GZIP) stream data. First marks the data in the output buffer with a compression endpoint, then sends this compressed stream data by executing a TCP SEND operation on the output buffer data.

Closing the Connection

Either the client or the server can end a TCP binding connection. The preferred way to close a connection is for the client to issue a CLOSE command for the TCP device. (Alternatively, the client may issue HALT command.) The server should then issue another READ command to that device and receive a <READ> error, then issue a CLOSE command for the TCP device.

The reason for this sequence is that, in accordance with the TCP/IP standard, connection resources are maintained for two minutes after a CLOSE, but only for the “active closer” — the process that performs the CLOSE first. Thus it is preferable to close the client first, because the resources of the server are usually more limited than those of the clients.

Disconnect with CLOSE Command

Issue this form of the CLOSE command from the client or server:

CLOSE "|TCP|devicenum"

As stated above, it is preferable for the client to issue the CLOSE command first. If the server issues the CLOSE command first, the client gets a <WRITE> error and should then issue a CLOSE command.

JOBSERVER Resources

If you are writing an InterSystems IRIS server to interface with clients over which you have no control, the server process must issue the CLOSE to close the TCP connection. The CLOSE command does close the connection as far as InterSystems IRIS is concerned, but internally TCP/IP retains resources for this connection on the server for up to two minutes.

This can have unexpected results when JOBSERVERs are used to service TCP/IP jobs. When a JOBSERVER process performs a halt, the process immediately returns to the pool of available JOBSERVER processes, but its resources are retained internally for up to two minutes. Because JOBSERVER processes are assigned on a first-available basis, it is possible for a heavy load from a relatively small number of clients to exhaust the resources of a JOBSERVER process.

To avoid this problem, a TCP/IP server opened by a JOB running under a JOBSERVER should explicitly issue a CLOSE, and then issue a brief HANG before the final QUIT (or HALT) command. In accordance with TCP/IP specification, a HANG 120 is required to guarantee no resources remain in use between incarnations in JOBSERVER. In practice, a HANG of one second is usually sufficient to evenly distribute resource load among JOBSERVER processes.

Automatic Disconnection

The TCP binding connection closes automatically under these conditions:

  • An InterSystems IRIS fatal error

  • RESJOB of the client or server process

  • iris stop

  • iris force

Effects of Disconnection

The effect of a disconnection on data remaining in the output buffer is determined by the /CLOSEFLUSH setting established during OPEN or USE. The default is to flush the data.

If one side closes a connection but the other side issues new WRITE commands, the first of these WRITE commands may succeed. Any additional WRITE commands receive a <WRITE> error.

From the client side, all READ commands to the side that closed the connection receive <READ> errors. The device must be closed and reopened to reestablish communication with the server.

From the server side, the first READ after a <READ> or <WRITE> error waits for and accepts a new connection.

You can use the %SYSTEM.TCPDevice.GetDisconnectCode()Opens in a new tab method to return the internal error that resulted in a <READ> or <WRITE> error on the current TCP device. $IO must be a TCP device.

See Also

FeedbackOpens in a new tab