NodeJS TCP

Home / NodeJS TCP

NodeJS TCP

December 9, 2015 | Uncategorized | No Comments

TCP or Transmission Control Protocol, is a connection oriented protocol for data communication and data transmission in network. It provides reliability over transmitted data so the packets sent or received is guaranteed to be in correct format and order.

Node has a first-class HTTP module implementation, but this descends from the “bare-bones” TCP module. Being so, everything described here applies also to every class descending from the net module.

TCP Server

We can create TCP server and client, using “net” module.

Here, how we create a TCP server.

require('net').createServer(function(socket) {
    // new connection
    socket.on('data', function(data) {
        // got data
    });

    socket.on('data', function(data) {
        // connection closed
    });

    socket.write('Some string');
}).listen(4001);

Here our server is created using “net” module and listen to port 4001 (to distinguish with our HTTP server in 4000). Our callback is invoked every time new connection arrived, which is indicated by “connection” event.

On this socket object, we can then listen to “data” events when we get a package of data and the “end” event when that connection is closed.

Listening

As we saw, after the server is created, we can bind it to a specific TCP port.

var port = 4001;
var host = '0.0.0.0';
server.listen(port, host);

The second argument (host) is optional. If omitted, the server will accept connections directed to any IP address.

This method is asynchronous. To be notified when the server is really bound we have to pass a callback.

//-- With host specified
server.listen(port, host, function() {
    console.log('server listening on port ' + port);
});

//-- Without host specified
server.listen(port, function() {
    console.log('server listening on port ' + port);
});

Write Data

We can pass in a string or buffer to be sent through the socket. If a string is passed in, we can specify an encoding as a second argument. If no encoding specified, Node will assume it as UTF-8. The operation are much like in HTTP module.

var flush = socket.write('453d9ea499aa8247a54c951', 'base64');

The socket object is an instance of net.Socket, which is a writeStream, so the write method returns a boolean, saying whether it flushed to the kernel or not.

We can also pass in a callback. This callback will be invoked when data is finally written out.

// with encoding specified
var flush = socket.write('453d9ea499aa8247a54c951', 'base64', function(){
    // flushed
});

// Assuming UTF-8
var flush = socket.write('Heihoo!', function(){
    // flushed
});

.end()

Method .end() is used to end the connection. This will send the TCP FIN packet, notifying the other end that this end wants to close the connection.

But, we can still get “data” events after we have issued this. It is simply because there still might be some data in transit, or the other end might be insisting on sending you some more data.

In this method, we can also pass in some final data to be sent:

socket.end('Bye bye!');

Other Methods

Socket object is an instance of net.Socket, and it implements the WriteStream and ReadStream interface, so all those methods are available like pause() and resume(). We can also bind to the “drain” events like other stream object can do.

Idle Sockets

A socket can be in idle state, or idle for some time. For example, there has been no data received at moment. When this condition happen, we can be notified by calling setTimeout():

var timeout = 60000;    // 1 minute
socket.setTimeout(timeout);
socket.on('timeout', function() {
    socket.write('idle timeout, disconnecting, bye!');
    socket.end();
});

or in shorter form:

socket.setTimeout(60000, function() {
    socket.end('idle timeout, disconnecting, bye!');
});

Keep-Alive

Keep-alive is mechanism to make the server prevent timeout. The concept is very simple: when we set up a TCP connection, we associate a set of timers and some of it deal with the keep-alive procedure. When the keep-alive timer reaches zero, we send our peer a keep-alive probe packet with no data in it and the ACK flag turned on.

In Node, all the functionality has been simplified. So, we can send keep-alive notification by invoking.

socket.keepAlive(true);

We can also speficy the delay between the last packet received and the next keep-alive packet on the second argument to the keep-alive call.

socket.keepAlive(true, 10000);    // 10 seconds

Delay or No Delay

When sending off TCP packets, the kernel buffers data before sending it off and uses the Naggle algorithm to determine when to send off the data. If you wish to turn this off and demand that the data gets sent immediately after write commands, use:

socket.setNoDelay(true);

Of course we can turn it on by simply invoking it with false value.

Connection Close

This method closes the server, preventing it from accepting new connections. This function is asynchronous, and the server will emit the “close” event when actually closed:

var server = ...
server.close();
server.on('close', function() {
    console.log('server closed!');
});

TCP Client

We can create a TCP client which connect to a TCP server using “net” module.

var net = require('net');
var port = 4001;
var host = 'www.google.com';
var conn = net.createConnection(port, host);

Here, if we omitted the host for creating connection, the defaults will be localhost.

Then we can listen for data.

conn.on('data', function(data) {
    console.log('some data has arrived');
});

or send some data.

conn.write('I send you some string');

or close it.

conn.close();

and also listen to the “close” event (either by yourself, or sent by peer)

conn.on('close', function(data) {
    console.log('connection closed');
});

Socket conforms to the ReadStream and WriteStream interfaces, so we can use all of the previously described methods on it.

Error Handling

When handling a socket on the client or the server, we can (and should) handle the errors by listening to the “error” event.

Here is simple template how we do:

require('net').createServer(function(socket) {
    socket.on('error', function(error) {
        // do something
    });
});

If we don’t catch an error, Node will handle an uncaught exception and terminate the current process. Unless that’s what we want, we should handle the errors.

, ,

About Author

about author

xathrya

A man who is obsessed to low level technology.

Leave a Reply

Your email address will not be published. Required fields are marked *

Social media & sharing icons powered by UltimatelySocial