TCP-Socket Transport¶
The TCP-socket-based transport layers a very simple protocol on top of ordinary TCP sockets:
- Processes act as either TCP-clients or -servers for a common port. There is one server and zero or more clients. Each client-server connection is a bi-direction stream of notifications which are sent and received by participants in the respective processes.
- Each process may host zero, one or many participants. Within a process, the participants share a connection.
Options¶
See also
- Configuration
- Specification of configuration mechanism.
The following configuration options are accepted by the TCP-socket-based transport:
Name Type Comment
+ transport
+-- socket
+---- host string Name of host running server
+---- port uint Port on which server listens
+---- portfile string Write automatically assigned port here
+---- server { 0, 1, auto } Act as server?
+---- tcpnodelay boolean Implementation detail
Note
The portfile
option is only supported by the Common Lisp
implementation as part of a special mode of operations which is
explained below.
Addresses and Ports¶
Server | Client | |
---|---|---|
Default address | localhost | 0.0.0.0 |
Default port | 55555 | 55555 |
It is possible to operate in “auto” mode instead of client or server mode. In that case the following actions are performed:
- Try to bind a listen socket to the configured address, port pair
- If this succeeds, act as server
- If this fails, goto 2
- Try to connect to a socket bound to the configured address, port
pair
- If this succeeds, act as client
- If this fails, give up
Note
This “auto” mode can only work properly for connections on a single computer: if a host other than the local host was used, it would be impossible to act as server when required.
In special cases, “auto” may still be useful for setups distributed over multiple computers but these cases require a detailed understanding of the above protocol and should generally be avoided.
Automatic Selection of an Unused Server Port¶
The combination of options port=0
, server=1
causes the server
to choose an unused port automatically. The purpose of the
portfile
option is obtaining this automatically assigned port.
The following values are supported
-
Write the selected port to the standard output stream.
-2
Write the selected port to the error output stream.
any other string
Interpret the string as a filename and write the selected port to that file. The file is overwritten, if it already exists.
Warning
This feature is only supported in the Common Lisp implementation.
Messages¶
The following messages are exchanged:
Name | Size [bytes] | Content | Comment |
---|---|---|---|
mzero | 4 | four 0 bytes | only used during handshake |
msize | 4 | size of payload in mpayload | little-endian |
mpayload | variable | payload blob | size is specified by previous msize |
Note
The handshake part of the protocol (explained below) is required to prevent the following scenario from happening:
- A client process connects to the TCP-socket of the server (without handshake)
- The client process creates a listener waiting for events from some remote participant
- The client process causes some remote participant to send an event which the listener should receive
- The event is not delivered to the listener since the connection is not yet fully established despite the fact that the listener was established before the event was caused.
Client Perspective¶
From the client’s perspective, the protocol consist of
- connect to the server socket
- receive mzero from the server
- concurrently send and receive length-delimited (via msize) notification messages mpayload
- shutdown; one of:
- error shutdown
- error in send or receive operation
- close socket
- passive orderly shutdown
- “end of file” in receive operation
- shutdown socket for writing
- close socket
- active orderly shutdown
- termination request from client program
- shutdown socket for writing
- wait for “end of file” from server
- close socket
- error shutdown
Server Perspective¶
The server establishes a listening TCP socket on the configured port. When a connection is accepted, the server continues to accept other connections and concurrently performs the following protocol on the new connection:
- accept client connection
- send mzero in to the client
- concurrently send and received notifications using length-delimited encoding via msize and mpayload
- shutdown; one of:
- error shutdown
- error in send or receive operation
- close socket
- passive orderly shutdown
- “end of file” in receive operation
- shutdown socket for writing
- close socket
- active orderly shutdown
- termination request from client program
- shutdown socket for writing
- wait for “end of file” from client
- close socket
- error shutdown
Example¶
# handshake
S -> C 0x00 0x00 0x00 0x00 0x00
# established
C -> S 0x23 0x00 0x00 0x00 # 35-byte payload follows
C -> S 0x12 0x34 0x56 0x78 0x9a ... # 35-byte payload blob
C -> S 0x03 0x00 0x00 0x00 # 3-byte payload follows
C -> S 0x12 0x34 0x56 # 3-byte payload blob
...
# shutdown
C -> S end-of-file
S -> C end-of-file
Implementations¶
Language | File(s) |
---|---|
C++ | “0.14” branch of https://code.cor-lab.org/git/rsb.git.cpp at src/rsb/transport/socket |
Java | “0.14” branch of https://code.cor-lab.org/git/rsb.git.java at src/rsb/transport/socket |
Python | /../rsb-python/rsb/transport/socket/__init__.py |
Common Lisp | “0.14” branch of https://code.cor-lab.org/git/rsb.git.cl at src/transport/socket |