To create a TCP client on a TouchBerry Pi or a Raspberry PLC, install a current LTS version of Node.js (from the NodeSource repository, the Debian package is too old) and use the net module that Node.js includes: net.createConnection() opens the connection to the IP and port of the server, write() sends data and the data event receives the reply. You run it with node client.js 192.168.1.30 5566. No extra npm package is needed.
This is part 2 of the tutorial. In part 1 the device got the static address 192.168.1.25. Here it becomes a TCP client that connects to a server, sends a message and prints the reply. The first version used a TouchBerry Pi 3, now discontinued. The steps are the same on the current TouchBerry Pi Panel PC and on any Raspberry PLC.
- Step 1Install Node.jsCurrent LTS version from NodeSource
- Step 2Write client.jsBuilt-in net module, no packages
- Step 3Test it locallyEcho server on the same device
- Step 4Connect to the serverIP and port of the real server
The network of the example
| Device | Role | Address |
|---|---|---|
| TouchBerry Pi or Raspberry PLC | TCP client | 192.168.1.25 (set in part 1) |
| PC, Raspberry Pi or Arduino PLC | TCP server | 192.168.1.30, port 5566 |
The server can be the Node.js TCP server of the same series, which answers with the data it receives, or an M-Duino with the TCP server for Arduino PLCs. Both devices must be in the same subnet or have a route between them.
Step 1: install Node.js LTS
First check if Node.js is already installed:
node -v
A Raspberry PLC prepared with the Industrial Shields image or install.sh script already has Node.js, because the script installs Node-RED with it. If node -v shows version 22 or later, go to step 2.
If Node.js is missing or older, do not install the nodejs package of Debian: Bookworm has Node.js 18, which reached its end of life in April 2025. Install the LTS version with the setup script of NodeSource, which publishes Node.js packages for Debian on arm64 and armhf:
sudo apt update
sudo apt install -y curl
curl -fsSL https://deb.nodesource.com/setup_lts.x -o nodesource_setup.sh
sudo -E bash nodesource_setup.sh
sudo apt install -y nodejs
node -v
setup_lts.x adds the repository of the current LTS line, and apt keeps Node.js updated with the rest of the system. To fix a major version instead, use setup_24.x or the version you need. This replaces the old setup_6.x script of the first version of this post: Node.js 6 has been out of support since 2019.
Step 2: write the TCP client
Create a folder for the project and open a new file:
mkdir ~/tcp-client
cd ~/tcp-client
nano client.js
Paste this code. The comments explain each part:
#!/usr/bin/env node
// TCP client: connects to a server, sends one line and prints the reply
const net = require('node:net');
const HOST = process.argv[2] || '127.0.0.1'; // IP address of the TCP server
const PORT = Number(process.argv[3]) || 5566; // TCP port of the server
const client = net.createConnection({ host: HOST, port: PORT }, () => {
console.log(`Connected to ${HOST}:${PORT}`);
client.write('Hello from the TCP client\n');
});
client.setTimeout(5000); // close if nothing happens for 5 s
client.on('timeout', () => {
console.log('No connection or no reply in 5 s');
process.exitCode = 1;
client.destroy(); // close the socket
});
client.on('data', (data) => {
console.log('Received: ' + data.toString().trim());
client.end(); // close the connection after the reply
});
client.on('error', (err) => {
console.error('Connection error: ' + err.message);
process.exitCode = 1;
});
client.on('close', () => {
console.log('Connection closed');
});
How it works:
process.argvreads the IP address and the port from the command line, so you can change the server without editing the code. Without arguments it uses127.0.0.1and port5566.net.createConnection()opens the connection. When it is open, the client sends one line ending in\n.- The
dataevent prints the reply and closes the connection withend(). setTimeout(5000)closes the socket if the server does not answer, or if the connection cannot be opened, in 5 seconds.- The
errorevent shows why the connection failed and sets the exit code to 1, so a script or a systemd service can detect it.
Save with Ctrl+O and exit with Ctrl+X.
Step 3: test the client on the same device
Before you use the network, test the client against a small echo server on the same device. Save this code as server.js in the same folder:
#!/usr/bin/env node
// TCP echo server to test the client: replies with the same data
const net = require('node:net');
const PORT = Number(process.argv[2]) || 5566;
net.createServer((socket) => {
console.log('Client connected: ' + socket.remoteAddress);
socket.on('data', (data) => socket.write(data)); // echo
socket.on('error', (err) => console.error('Socket error: ' + err.message));
socket.on('close', () => console.log('Client disconnected'));
}).listen(PORT, () => console.log('Listening on port ' + PORT));
Start the server in one terminal:
node server.js
And run the client in a second terminal:
node client.js
The client must print:
Connected to 127.0.0.1:5566
Received: Hello from the TCP client
Connection closed
Stop the server with Ctrl+C.
Step 4: connect to the real server
Start the server on the other device and give the client its IP address and port:
node client.js 192.168.1.30 5566
If it does not connect, the message tells you where to look:
| Message | Likely cause | What to check |
|---|---|---|
ECONNREFUSED | The device answers, but nothing listens on that port | The server is running and the port is the same on both sides |
EHOSTUNREACH or ENETUNREACH | No route to the server | Address and subnet of both devices with ip a and ip route (part 1) |
No connection or no reply in 5 s | The server does not answer, or the address does not exist | Cable, ping 192.168.1.30, and that the server replies to each message |
An Arduino based server usually reads until the end of the line, which is why the client ends its message with \n.
FAQ about TCP clients with Node.js
Do I need to install a package with npm?
No. The net module is part of Node.js. You do not need npm install for this example.
Which Node.js version should I use?
A version in LTS (long-term support). Up to Node.js 26, only the versions with an even number become LTS; from Node.js 27 (April 2027) there is one major release a year and every one becomes LTS in October. Each LTS line receives security updates for about 30 months. Check node -v from time to time and update with sudo apt upgrade. The apt command does not jump to a new major version: to move up, change the NodeSource repository by running its setup script again (for example setup_lts.x).
How do I keep the connection open and send data every second?
Do not call end() in the data event and send the data with setInterval(). Add a reconnection in the close event if the client must recover when the server restarts.
How do I start the client when the device boots?
Create a systemd service that runs node /home/pi/tcp-client/client.js with the address of the server. Adapt the path to your user.
TCP with Industrial Shields devices
- Part 1: set a static IP address
- TCP server with Node.js
- TCP server on an Arduino PLC
- TCP client on an Arduino PLC
The TouchBerry Pi Panel PC (7", 10.1" and 18.5") and the Raspberry PLC run Linux, so the same Node.js client works on both.
Take it further
A TCP connection is how a panel or a Linux PLC talks to the rest of the line. These pages use it in real projects.
PLC Solution Library
TCP socket between Python and Node-RED on a Raspberry PLC
A Python control process and a Node-RED dashboard exchange encoder data and start, stop and exit commands over TCP.
See the example
Case study
Water bottling with a TouchBerry Pi Panel PC
A TouchBerry Pi 7" runs a water bottling station as PLC and HMI: conveyor, sensors, cylinder and pump on its own I/O.
Read the case study