TCP Advanced Topics
This page discusses several advanced topics in communication between InterSystems IRIS® data platform processes using TCP/IP.
Connection Management
The server maintains only one connection at a time. If a second client tries to connect while another connection is open, TCP/IP places that client in a queue. While in the queue, the second client can write to the port as if it were connected. The data the second client writes remains in a buffer until the first connection is closed and the second client connects.
The second client hangs if it issues a READ before the connection exists. Any connection attempt by a third client while the second one is in the queue fails.
If a client that has already opened a TCP device tries to connect a second time while the first connection still exists, the second OPEN command causes a <COMMAND> error. Treating this situation as an error rather than as a USE command prevents surprising results. Such unexpected results could occur if an erroneous program thinks it has opened a new connection, when it is actually reusing an existing connection that may have a different destination or different parameters.
To handle multiple clients, see below.
Job Command with TCP Devices
You can use the JOB command to implement a TCP concurrent server. A TCP concurrent server allows multiple clients to be served simultaneously. In this mode, a client does not have to wait for the server to finish serving other clients. Instead, each time a client requests the server, it spawns a separate subjob for that client which remains open as long as the client needs it. As soon as this subjob has been spawned (indicated by the return of the JOB command), another client may request service and the server will create a subjob for that client as well.
A concurrent server uses the JOB command with the switch concurrent server bit (bit 4 or bit 16) set. Bit 16 is the recommended setting.
-
If bit 4 is set, the JOB command passes to the spawned process the TCP device in the principal input and principal output process parameters. Whenever you include bit 4 in switch, you must specify the TCP device in both principal input and principal output process parameters. You must use the same device for both principal input and principal output. Use of bit 4 is not recommended; see JOB command in the ObjectScript Reference for further details.
-
If bit 16 is set, the JOB command passes to the spawned process three separate devices for the TCP device, the principal input, and principal output process parameters. You specify two of these TCP devices in the JOB command, using the principal input and principal output process parameters. You can also default these parameters, as shown in the following examples: JOB child:(:16:input:output) or JOB child:(:16::)).
See JOB command in the ObjectScript Reference for an example and further details.
Before you issue the JOB command, the device(s) you specify for principal input and principal output must:
-
Be open
-
Be listening on a TCP port
-
Have accepted an incoming connection
After the JOB command, the device in the spawning process is still listening on the TCP port, but no longer has an active connection. The application should check $ZA after issuing the JOB command to make sure that the CONNECTED bit in the state of the TCP device was reset.
The spawned process starts at the designated entry point using the specified TCP device. The TCP device has the same name in the child process as in the parent process. The TCP device has one attached socket. The inherited TCP device is in S (stream) mode. However, the child process can change the mode with a USE command. We recommend that the server open TCP device in the A (accept) mode.
The TCP device in the spawned process is in a connected state: the same state the device would receive after it is opened from a client. The spawned process can use the TCP device with USE 0 or USE $P. It can also use the TCP device implicitly (if switch=4). However, for the following reasons switch=16 is preferable to switch=4:
-
When switch=4, if a <READ> error occurs on the principal device, the job simply halts, without taking an error trap. This is because when switch=4 the TCP device is the principal device. To support error trapping, use switch=16 and specify another device for the TCP device.
-
When switch=4, if the remote TCP device closes down the connection, the job simply halts, without taking an error trap. To override this default behavior and generate a <DSCON> error, you must set the DisconnectErr()Opens in a new tab method of the %SYSTEM.ProcessOpens in a new tab class.
You can use the %SYSTEM.SocketOpens in a new tab class methods, rather than the JOB command, to create concurrent TCP server connections. However, note that the %SYSTEM.SocketOpens in a new tab methods assume that the worker jobs are already started. You can use these methods for concurrent TCP server connections if you do not need the listener job to start the worker jobs, and the listener job knows Process IDs (PIDs) of the worker jobs.
Concatenation of Records
In certain situations, TCP concatenates separate records to form a single record. Concatenation can occur if a client or server process issues a series of WRITE commands to a TCP port, separated by WRITE ! or WRITE # commands to flush the buffer, whether or not a READ command is waiting at the other end of the connection.
The first example below outlines how Process A receives two separate records when it has a READ command waiting as Process B writes two records to the TCP port.
Process A Process B
%SYS> USE "|TCP|41880" R A U 0 W A %SYS> USE "|TCP|41880" WRITE "ONE",!,"TWO"
<RETURN> <RETURN>
ONE
%SYS> USE 41880 R A U 0 W A
<RETURN>
TWO
The second example outlines how Process A receives one concatenated record when it issues its READ command after Process B has finished writing two records to the TCP port.
Process A Process B
. %SYS> USE "|TCP|41880" WRITE "ONE",!,"TWO"
. <RETURN>
ONE
%SYS> USE "/TCP/41880" R A U 0 W A
<RETURN>
ONETWO
Multiplexing InterSystems IRIS TCP Devices
The %SYSTEM.SocketOpens in a new tab class provides methods for multiplexing InterSystems IRIS TCP devices. The Fork() and Select() methods allow you to have a single job handling both accepting new connections and reading data from a connected TCP device at the same time. After a listening TCP device received a connection, use Fork()Opens in a new tab to create a new TCP device for reading data. The original listening TCP device continues to accept incoming connections. You use the Select()Opens in a new tab method to wait for both listening and connected TCP devices. When a new connection arrived or data becomes available, Select() returns the device name that was signaled.
You can use the Select()Opens in a new tab, Publish()Opens in a new tab, Export()Opens in a new tab, and Import()Opens in a new tab methods to have a listener job accept an incoming connection and pass the connected device to a worker job. This worker job could communicate with the remote client.
For further details and program examples, see %SYSTEM.SocketOpens in a new tab class in the InterSystems Class Reference.