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.

"use strict";

const net = require("net");

const proxyPort = 9020;
const tcpServerPort = 9030;

// proxy server
const proxy = net.createServer(function (socket) {
  console.log("Client connected to proxy");

  // Create a new connection to the TCP server
  const 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
const 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: