A simple Node.js TCP proxy

I'm working on an interesting project that required the use of a TCP proxy. I haven't really worked with TCP sockets before, so it is lucky that Node.js makes it quite so easy. :)

The following is a basic example of such a proxy.

/*jshint node:true*/
'use strict';

var net = require('net');

var proxyPort = 9020;
var tcpServerPort = 9030;

// proxy server
var proxy = net.createServer(function (socket) {
    var client;

    console.log('Client connected to proxy');

    // Create a new connection to the TCP server
    client = net.connect(tcpServerPort);

    // 2-way pipe between client and TCP server
    socket.pipe(client).pipe(socket);

    socket.on('close', function () {
        console.log('Client disconnected from proxy');
    });

    socket.on('error', function (err) {
        console.log('Error: ' + err.soString());
    });
});

// a simple TCP server for testing
var server = net.createServer(function (socket) {
    console.log('Client connected to server');

    socket.on('close', function () {
        console.log('Client disconnected from server');
    });

    socket.on('data', function (buffer) {
        // 'echo' server
        socket.write(buffer);
    });

    socket.on('error', function (err) {
        console.log('Error: ' + err.soString());
    });
});

server.listen(tcpServerPort);
proxy.listen(proxyPort);

To test, we can connect to our server using something like telnet, or netcat.

First we test connecting to the TCP server directly (it is an "echo" server, meaning it returns whatever we send to it):

telnet localhost 9030
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
hello

The server will log:

Client connected to server
Client disconnected from server

Now we connect via the proxy:

telnet localhost 9020
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
hello

The server will now log:

Client connected to proxy
Client connected to server
Client disconnected from proxy
Client disconnected from server

The way this works is that both the client-proxy and proxy-server connections are streams and one useful property that streams have is that they can be joined together using a pipe, as done in this basic example.

Further reading: