Using The TCP Bridge

The stream TCP bridge classes allows a Rogue stream to be bridged over a TCP network interface. The bridge consists of a server and a client. The server, TcpServer, listens for incoming connections on a pair of TCP ports. The client, TcpClient, connects to the server at a specific address. Both ends of the bridge are bi-directional allowing a full duplex stream to be bridged between the server and client.

Python Server

The following code demonstrates a Python server with a local receiver and transmitter device. The local transmitter will send data to a remote receiver on the client. The local receiver will receive data from a remote transmitter on the client. The Python server is able to interface with either a Python or C++ client.

import rogue.interfaces.stream
import pyrogue

# Local transmitter
src = MyCustomMaster()

# Local receiver
dst = MyCustomSlave()

# Start a TCP Bridge Server, Listen on ports 8000 & 8001 on localhost
# Pass an address of 192.168.1.1 to listen on only that specific interface
tcp = rogue.interfaces.stream.TcpServer("127.0.0.1",8000)

# Connect the transmitter and the receiver
src >> tcp >> dst

Python Client

The following code demonstrates a Python client with a local receiver and transmitter device. The local transmitter will send data to a remote receiver on the server. The local receiver will receive data from a remote transmitter on the server. The Python client is able to interface with either a Python or C++ server.

import rogue.interfaces.stream
import pyrogue

# Local transmitter
src = MyCustomMaster()

# Local receiver
dst = MyCustomSlave()

# Start a TCP Bridge Client, Connect remote server at 192.168.1.1 ports 8000 & 8001.
tcp = rogue.interfaces.stream.TcpClient("192.168.1.1",8000)

# Connect the transmitter and the receiver
src >> tcp >> dst

C++ Server

The following code demonstrates a C++ server with a local receiver and transmitter device. The local transmitter will send data to a remote receiver on the client. The local receiver will receive data from a remote transmitter on the client. The C++ server is able to interface with either a Python or C++ client.

#include <rogue/interfaces/stream/TcpServer.h>

// Local transmitter
MyCustomMasterPtr src = MyCustomMaster::create()

// Local receiver
MyCustomSlavePtr dst = MyCustomSlave::create()

// Start a TCP Bridge Server, Listen on localhost, ports 8000 & 8001.
// Pass an address of 192.168.1.1 to listen on only that specific interface
rogue::interfaces::stream::TcpServerPtr tcp = rogue::interfaces::stream::TcpServer::create("127.0.0.1",8000)

// Connect the transmitter
*( *src >> tcp ) >> dst;

C++ Client

The following code demonstrates a C++ client with a local receiver and transmitter device. The local transmitter will send data to a remote receiver on the server. The local receiver will receive data from a remote transmitter on the server. The C++ client is able to interface with either a Python or C++ server.

#include <rogue/interfaces/stream/TcpClient.h>

// Local transmitter
MyCustomMasterPtr src = MyCustomMaster::create()

// Local receiver
MyCustomSlavePtr dst = MyCustomSlave::create()

// Start a TCP Bridge Client, Connect remote server at 192.168.1.1 ports 8000 & 8001.
rogue::interfaces::stream::TcpClientPtr tcp = rogue::interfaces::stream::TcpClient::create("192.168.1.1",8000)

// Connect the transmitter
*( *src >> tcp ) >> dst;

Resource Configuration For Multiple Streams

To use multiple rogue streams, ensure that the appropriate operating-system-level settings have been enabled. The following (non-optimized) settings allow for the parallel launch of 2043 TCP servers on a RedHat Enterprise Linux 7.9 machine. See the steps below.

Use sysctl calls to set max number of open files/sockets, threads and max_map_count:

sysctl -w fs.file-max=262140
sysctl -w kernel.threads-max=1014712
sysctl -w vm.max_map_count=2097152

Confirm with:

cat /proc/sys/fs/file-max
cat /proc/sys/kernel/threads-max
cat /proc/sys/vm/max_map_count

Edit /etc/security/limits.conf and add the following:

* soft     nproc          8192
* hard     nproc          8192
* soft     nofile         524280
* hard     nofile         524280

Ensure the following limits:

(rogue_build) [skoufis@pc94331 ~]$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 126839
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 524280
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 8192
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited