To start with the basics, one of the popular open source JavaScript runtime environments is Node.js. Node is built on Chrome's V8 JavaScript engine. Node.js is mostly used for building server-side and networking applications. TCP (Transmission Control Protocol) is a networking protocol that enables reliable, ordered, and error-checked delivery of a stream of data between applications. For both sides to exchange data streams, a TCP server must accept a TCP connection request, and the connection is then established.

We can write two types of TCP socket programs: server and client. The server's function is to listen for connections from the client and then send the processed data back. This communication happens via sockets.

The TCP Programming in Node.js requires an internal module called net and it works as an asynchronous wrapper for network programming. net is an extensive module, whereas, for this tutorial, we'll only cover TCP Server and Client. We will be using Alibaba Cloud Elastic Compute Service (ECS) to build the Server and Client.

Getting Started

To follow this tutorial, you will need a machine running a Linux/Unix distribution such as Ubuntu or MacOS, a code editor/IDE with Node.js installed on it, and a basic working knowledge of Node.js. In this tutorial, we won't be deploying the application for production but simply running it on our development machine and testing it from there.

Creating a TCP Server

To begin, create a directory where you would like to store your application. For this tutorial, we will create our application in ~/nodejs-tcp-app .

In this tutorial, we will be doing most of our work with the terminal and also using the nano editor in the terminal to help ensure the process remains the same for all the platforms.

To start, open your terminal:

mkdir ~/nodejs-tcp-app

Now, switch to the newly created directory and run npm init to create the package.json file.

cd ~/nodejs-tcp-app && npm init

Now, the terminal will prompt you for basic information about the project. Add the name, author, and main file as server.js and create the file. You should see the package.json file in the directory now.

Next, we will create the server.js file which will have the code for our TCP Server.

Now, enter the following command in the same directory which will create the server.js file and open the text editor to write the code.

nano server.js

To start with, we'll import the net module which comes pre-shipped in Node.js and define the port and the host to run the server and then create an instance of the server.

const net = require('net'); //define host and port to run the server const port = 8080; const host = '127.0.0.1'; //Create an instance of the server const server = net.createServer(); //Start listening with the server on given port and host. server.listen(port,host,function(){ console.log(`Server started on ${host}:${port}`); });

This is the basic building block of our application and should be enough to start the TCP server.

Next, we need to add a listener to the connection which the client connects.

Edit the server declaration to add a connection listener function called onClientConnection and then declare the function at the bottom.

const net = require('net'); //define host and port to run the server const port = 8080; const host = '127.0.0.1'; //Create an instance of the server const server = net.createServer(onClientConnection); //Start listening with the server on given port and host. server.listen(port,host,function(){ console.log(`Server started on port ${port} at ${host}`); }); //Declare connection listener function function onClientConnection(sock){ //Log when a client connnects. console.log(`${sock.remoteAddress}:${sock.remotePort} Connected`); //Listen for data from the connected client. sock.on('data',function(data){ //Log data from the client console.log(`${sock.remoteAddress}:${sock.remotePort} Says : ${data} `); //Send back the data to the client. sock.write(`You Said ${data}`); }); //Handle client connection termination. sock.on('close',function(){ console.log(`${sock.remoteAddress}:${sock.remotePort} Terminated the connection`); }); //Handle Client connection error. sock.on('error',function(error){ console.error(`${sock.remoteAddress}:${sock.remotePort} Connection Error ${error}`); }); };

So in the onClientConnection function, we expect the connection object sock and then create three event listeners namely data , close and error .

In the data event listener, we console log the data received from the client and send it back to the client, and in the close event listener, we handle the connection termination and console log the same. error event listener handles connection error from the client.

This should complete our server.js code and now, we have a working TCP application which accepts TCP client connections, listens for data on them and echoes it back to the client. Now, save the file and exit the nano editor.

Let's create our TCP client using the same module.

Creating a TCP Client

Let's create our client.js file using nano command and start working on it.

nano client.js

Just like we did with server.js , let's import the net module and define the config arguments.

const net = require('net'); //define the server port and host const port = 8080; const host = '127.0.0.1'; //Create an instance of the socket client. const client = new net.Socket(); //Connect to the server using the above defined config. client.connect(port,host,function(){ console.log(`Connected to server on ${host}:${port}`); //Connection was established, now send a message to the server. client.write('Hello from TCP client'); }); //Add a data event listener to handle data coming from the server client.on('data',function(data){ console.log(`Server Says : ${data}`); }); //Add Client Close function client.on('close',function(){ console.log('Connection Closed'); }); //Add Error Event Listener client.on('error',function(error){ console.error(`Connection Error ${error}`); });

So this should be it for our client.js file, which will connect to the server, send a message upon connection, and log the response from the server.

Here we have again added three event listeners just like the server to handle data, connection termination, and connection errors.

Now, save the file and exit the nano editor.

Testing the Connection

As we are done with creating our TCP-based server and client app, we now need to start our server and connect the TCP client with the server.

For this, we'll need two terminal sessions: one for the server and another for the client.

In the first one, we'll start the server using the following command:

node server.js

This command should start the TCP server and in the terminal, you should see the log:

Server started on 127.0.0.1:8080

Next, we need to start our TCP client file to connect to the server and send the message. In the other terminal type the following command:

node client.js

This should spawn our TCP client which will then try to connect to the server and send the message. Now, on your terminal, you should see the following text.

Connected to server on 127.0.0.1:8080 Server Says : You Said Hello from TCP client

So now we know that the client was able to connect to the server and that it received the echo back which we were able to log.

Next, when you go back to the terminal session running the server, you should see this. However, the client port may vary:

127.0.0.1:56330 Connected 127.0.0.1:56330 Says : Hello from TCP client

We aren't programmatically closing the client connection, hence the close event listener won't be triggered. However, if you go back to the client terminal and press ^c , the client will be terminated and, in the server terminal, you should get the log for connection termination.

127.0.0.1:56330 Terminated the connection

We have successfully tested our TCP server and client.

Conclusion

In this tutorial, we created a TCP application with Node.js on Alibaba Cloud Elastic Compute Service (ECS) instances. We can do a lot more with TCP Sockets, as this was just an introductory program. An advanced version of this could be a chat room enabling people to send and receive messages through the TCP Server. You can also use it to handle large chunks of data streams for real-time data communication.