Simple TCP Application using NodeJS

PARAB
6 min readFeb 11, 2023

--

Agenda:

  • To code a simple TCP server/client (remember here we are not talking about ``HTTP`` server/client its plain ``TCP``)
  • To deploy that code on AWS EC2
  • To configure Nginx so that we can use our application

Prerequisites:

  • Some basic NodeJS
  • An EC2 instance up and running
  • Understanding of Nginx (optional)

I will be considering that you should have understanding of above things,

It’s not true at all …. hahaha

So guys, first of all let us be clear about what a TCP server and client is !

So, as we all know that there are two main types of connection protocols i.e. UDP (User Datagram Protocol) and TCP (Transmission Control Protocol) each of which, by the way, we , at least once, have heard somewhere or we have studied in school or universities.

As we hear the word client/server, we immediately think of an HTTP server having some API endpoints on backend and serving the browser or some HTTP client application.

And in short TCP and UDP can be described as :
``For sending data packets over a network we have two options :-
One is to send packets over a connection that is reliable i.e. which can make sure that our packet reached to the receiver’s end. And another is to send data packets over a non-reliable connection which do not make sure just receives data which receives to it.

Here, the reliable one is TCP and unreliable is UDP.``

Both the protocols stated above have their own pros & cons. You can know more on Google :)

HTTP is an protocol which is built on TCP therefore it is reliable. So, now we understand why we use HTTP for our web application. So that we don’t our data to be lost and we want to make sure that our data reached to the destination.

May be you would have made numerous HTTP servers using node (assuming) but we rarely get a chance to make pure TCP server.

In this write-up we will be doing that, so let’s start…

Coding Time :)

Let’s start by writing out our server code first

//Require the net module which comes with NodeJS
const net = require('net');

//Declare the port to which out server will listen
const PORT = 6969;

//Create the server
const server = net.createServer();

//Now let the server know what to do when some client makes a connection
server.on('connection', function(sock) {

//Logging host:port of the tcp_client that connects
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);

//define the function to run when client sends some data
sock.on('data', function(data) {

//log the data
console.log('DATA ' + sock.remoteAddress + ': ' + data);

//send some response to client
sock.write('Hello client from server');
});

//define the function to run when client disconnects
sock.on('end', function() {
console.log('CONNECTION CLOSED: ' + sock.remoteAddress + ':' + sock.remotePort);
});

//also we want to see if some error occurs
sock.on('error', function(err) {
console.log(`Error ${sock.remoteAddress}: ${err}`);
});
});

//now let's start listening for connections
server.listen(PORT, () => {
console.log('TCP Server is running on port ' + PORT + '.');
});

See, its not that complex it can be related to express.js or rather we can say web sockets would be more look-a-like … haha!

Now, write code for our client so that we can use it to send some data and test our server

const Net = require('net');

const port = 5000;
const host = 'YOUR_SERVER_IP'; //if you are on localhost then, 127.0.0.1

//make a socket instance which will be our client
const client = new Net.Socket();

//connect to the server
client.connect({ host, port }, function() {
console.log('TCP connection established with the server.');

//send data to server
client.write('hello server from client.');
});

//define what to be done when server sends some data
client.on('data', function(chunk) {
console.log(`Data received from the server: ${chunk.toString()}.`);
//can close the connection using below command
// client.end();
});

//define what to do when client disconnects
client.on('end', function() {
console.log('Requested an end to the TCP connection');
});

And that’s it …. Finally coding part is over…

Deploy to EC2

For this there are many ways, simplest way is to ssh into your EC2 instance. And follow the following steps.

Make sure you have node installed on the instance.

#make a directory and go into it
$ mkdir node_tcp && cd node_tcp

#make a file named server.js
$ touch server.js

#use any text editor,say vim, and paste the server code (written in coding section) in it and save the file
$ vi server.js

#run our server
node server.js

You should see something like this in your console

It means our server successfully started.

Now, let’s setup nginx so that we can access it.

Nginx configuration

I always see nginx configuration as a tediuos albeit critical job to do. Let’s do it.

You would have probably used nginx for your http server which will be like defining server details inside an http block inside ngnix.conf

But it would not work here, we have to do something different

  • Open nginx config file (remember do this in the default nginx file otherwise it will not work)
sudo vi /etc/nginx/nginx.conf
  • Add the following code below http block to the end of the file to route tcp connections to our server running on port 6969
stream {
upstream tcp_connection{
server 127.0.0.1:6969 max_fails=3 fail_timeout=30s;
}
server {
listen 5000;
proxy_pass tcp_connection;
}
}
  • Above code will make a upstream named tcp_connection. Here, we define the address where we want to redirect tcp connections. And a server, which will listen on port 5000 that will be used by our client applications.
  • Save the file.
  • Test the nginx config for any syntax errors
sudo nginx -t
  • Restart the nginx to load the new config
sudo service nginx restart

Now, if you get error like below in starting nginx,

unknown directive "stream" in /etc/nginx/nginx.conf

that might be because to make stream block work in nginx you must tell it before using it (may be latest versions has fixed it or included it by default)

On EC2 we can do something like

sudo yum install nginx-mod-stream
  • It will install the required module and we do not have to do nothing else except restarting our nginx

But on centos we must load the module in the nginx.conf file itself. To do that write the following code to the top of your nginx.conf file

load_module /usr/lib/nginx/modules/ngx_stream_module.so;
  • For other OS just search around for this module and load it

Hence, our TCP server is now up and running.

Now, go to your aws console and open the port 5000 for TCP requests.

And We can now test our server.

  • Copy the code of client from coding section and paste in client.js file in your local machine.
  • Update your server IP in the file
  • Run the file
node client.js

You can see logs on our server like this

And on client side too

We did it…

Congrats. :)

See you next time.

Connect with me :

~ GitHub
~ LinkedIn
~ Twitter

--

--

PARAB
PARAB

Written by PARAB

Cybersecurity Enthusiast || AWS || GCP || Full Stack Developer || Docker

No responses yet