Skip to Content

TCP server with Node.js on a TouchBerry Pi or Raspberry PLC

Install Node.js LTS, write an echo server with the net module, test it with the client of part 2 and start it at boot with systemd
December 10, 2018 by
TCP server with Node.js on a TouchBerry Pi or Raspberry PLC
Alejandro Jabalquinto

To create a TCP server on a TouchBerry Pi Panel PC or a Raspberry PLC, install a current LTS version of Node.js and use its built-in net module. net.createServer() handles each client that connects, and listen(5566) opens the port on every network interface of the device. The example in this post is an echo server: it replies with the same data it receives.

The server is the other end of the Node.js TCP client of the same series. It works with that client, with an Arduino PLC as client or with any tool that opens a TCP connection.

The first version of this post used a TouchBerry Pi 3, now discontinued, and Node.js 6. The steps are the same on the current TouchBerry Pi Panel PC and on any Raspberry PLC, because both run Raspberry Pi OS (Debian).

TouchBerry Pi Panel PC 18.5 inch with a dashboard on the touch screen
TouchBerry Pi Panel PC 18.5": it can run the TCP server of this tutorial.
  1. Step 1Install Node.jsCurrent LTS version from NodeSource
  2. Step 2Write server.jsBuilt-in net module, no packages
  3. Step 3Test itOn the device, then from the client
  4. Step 4Start it at bootA systemd service

The network of the example

DeviceRoleAddress
TouchBerry Pi or Raspberry PLCTCP server192.168.1.30, port 5566
TouchBerry Pi, Raspberry PLC, PC or Arduino PLCTCP client192.168.1.25

A server needs an address that does not change, or the clients will not find it after a reboot. Give it a static IP address first, with nmcli on Bookworm and Trixie or with dhcpcd.conf on older systems. The steps are in how to set a static IP address on a TouchBerry Pi or Raspberry PLC.

Both devices must be in the same subnet, or have a route between them. Check it with ip a and ip route.

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:

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

This replaces the setup_6.x script of the first version of this post. Node.js 6 has been out of support since 2019, and that script no longer installs a supported version.

Step 2: write the TCP server

Create a folder for the project and open a new file:

mkdir -p ~/tcp-server
cd ~/tcp-server
nano server.js

Paste this code. The comments explain each part:

#!/usr/bin/env node
// TCP server: accepts several clients and replies with the same data (echo)
const net = require('node:net');

const PORT = Number(process.argv[2]) || 5566; // TCP port to listen on
const HOST = '0.0.0.0'; // all IPv4 addresses of the device: eth0, eth1, wlan0

const server = net.createServer((socket) => {
  const who = `${socket.remoteAddress}:${socket.remotePort}`;
  console.log('Client connected: ' + who);

  socket.on('data', (data) => {
    console.log(`Received from ${who}: ${data.toString().trim()}`);
    socket.write(data); // reply with the same data
  });

  socket.on('error', (err) => console.error(`Error with ${who}: ${err.message}`));
  socket.on('close', () => console.log('Client disconnected: ' + who));
});

server.on('error', (err) => {
  console.error('Server error: ' + err.message); // for example EADDRINUSE
  process.exit(1);
});

server.listen(PORT, HOST, () => {
  console.log(`TCP server listening on ${HOST}:${PORT}`);
});

How it works:

  • net.createServer() runs the function once for each client that connects. Several clients can be connected at the same time.
  • listen(PORT, '0.0.0.0') opens the port on all the IPv4 addresses of the device, so the clients can use the address of eth0, eth1 or the Wi-Fi.
  • The data event receives what the client sends, and socket.write() sends it back.
  • The error event of the server stops the program with exit code 1 if the port cannot be opened, for example when another program uses it.

The port comes from the command line, so node server.js 6000 listens on port 6000. Without an argument it uses 5566, like the client of part 2. Save with Ctrl+O and exit with Ctrl+X.

Step 3: test the server

Start the server:

node server.js

In a second terminal on the same device, connect with nc (netcat) and type a line. The server sends the same line back. Close nc with Ctrl+C. If nc is missing, install it with sudo apt install netcat-openbsd.

nc 127.0.0.1 5566

Then test from the other device with the client of part 2, with the address of the server:

node client.js 192.168.1.30 5566

The client prints the reply:

Connected to 192.168.1.30:5566
Received: Hello from the TCP client
Connection closed

And the server shows who connected and what it received:

TCP server listening on 0.0.0.0:5566
Client connected: 192.168.1.25:50412
Received from 192.168.1.25:50412: Hello from the TCP client
Client disconnected: 192.168.1.25:50412

If the client cannot connect, check the server side first:

SymptomLikely causeWhat to do
EADDRINUSE when the server startsAnother program, or another copy of the server, uses the portStop it, or start the server with another port
EACCES when the server startsPorts below 1024 need root permissionsUse a port from 1024 up, like 5566
The client gets ECONNREFUSEDNothing listens on that address and portCheck with ss -ltnp | grep 5566 that the server listens
The client gets a timeoutWrong address, no route or a firewall in betweenCheck ip a on the server and ping 192.168.1.30 from the client

Step 4: start the server when the device boots

On a machine, the server must start on its own after a power cut. A systemd service does it. First check where node is:

which node

With the NodeSource packages, the answer is /usr/bin/node. Create the service file:

sudo nano /etc/systemd/system/tcp-server.service

Paste this content. Change the user pi and the folder if yours are different:

[Unit]
Description=TCP echo server with Node.js
After=network-online.target
Wants=network-online.target

[Service]
User=pi
WorkingDirectory=/home/pi/tcp-server
ExecStart=/usr/bin/node /home/pi/tcp-server/server.js 5566
Restart=on-failure

[Install]
WantedBy=multi-user.target

Enable and start the service, check its state and follow its messages:

sudo systemctl daemon-reload
sudo systemctl enable --now tcp-server
systemctl status tcp-server
journalctl -u tcp-server -f

Restart=on-failure starts the server again if it stops with an error. Leave the log with Ctrl+C: the service keeps running.

FAQ about TCP servers with Node.js

Do I need to install a package with npm?

No. The net module is part of Node.js, so this server does not need npm install.

Can several clients connect at the same time?

Yes. Node.js calls the function of createServer() for each connection, and each client has its own socket. The test of this post connected three clients at once.

How do I read complete messages?

TCP sends a stream of bytes, not messages. One data event can bring half a message or two messages. If your clients end each message with \n, keep the data in a buffer and process it line by line.

Which Node.js version should I use?

A version in LTS (long-term support), which receives security updates for about 30 months. Up to Node.js 26 only even-numbered versions become LTS; from Node.js 27 every major version does. Check node -v from time to time.

TCP with Industrial Shields devices

The TouchBerry Pi Panel PC (7", 10.1" and 18.5") and the Raspberry PLC run Linux, so the same Node.js server 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.

​Search in our Blog

TCP server with Node.js on a TouchBerry Pi or Raspberry PLC
Alejandro Jabalquinto December 10, 2018
Share this post
Tags

Looking for your ideal Programmable Logic Controller?

Take a look at this product comparison with other industrial controllers Arduino-based. 

We are comparing inputs, outputs, communications and other features with the ones of the relevant brands.

PLC Comparison