JavaScript · Course navigation

JavaScript: a TCP echo server with the net module

Send a line through a TCP socket and print the server's reply.

On this page
Before you start

JavaScript callbacks and events.

  • Send a line through a TCP socket and print the server's reply.
  • Predict the sample output and explain the state changes.
  • Complete the practice task and check the boundary cases.

The concept

TCP gives two programs a reliable stream of bytes. The net module exposes it directly. net.createServer calls your handler for each new connection with a socket, and a socket emits a data event whenever bytes arrive and a close event when the connection ends.

The server in this example replies to the first chunk it receives and then closes its side with socket.end. The client connects, writes a line, prints what comes back, and closes the server when its own socket is closed. TCP is a stream, so one write is not guaranteed to arrive as one data event. Real protocols need delimiters or length prefixes.

Code example

JavaScript
const net = require("node:net");

const server = net.createServer((socket) => {
  socket.on("data", (chunk) => {
    socket.end("echo: " + chunk.toString().trim() + "\n");
  });
});

server.listen(0, "127.0.0.1", () => {
  const client = net.connect(server.address().port, "127.0.0.1", () => {
    client.write("hello\n");
  });
  client.on("data", (reply) => {
    console.log(reply.toString().trim());
  });
  client.on("close", () => server.close());
});
Output
echo: hello

Follow the code

Open the walkthrough to inspect the example one step at a time.

Show guided walkthrough
Guided walkthroughReady
1const net = require("node:net");
2
3const server = net.createServer((socket) => {
4 socket.on("data", (chunk) => {
5 socket.end("echo: " + chunk.toString().trim() + "\n");
6 });
7});
8
9server.listen(0, "127.0.0.1", () => {
10 const client = net.connect(server.address().port, "127.0.0.1", () => {
11 client.write("hello\n");
12 });
13 client.on("data", (reply) => {
14 console.log(reply.toString().trim());
15 });
16 client.on("close", () => server.close());
17});

Follow the example

Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.

View the complete dry-run table
Prepared trace of the published program. Some rows group repeated iterations.
Step / lineWhat happensState after stepOutput so far
The handler runs for every incoming connection.—
—
Listen on the loopback address and any free port.—
—
The client sends a line once the connection is established.—
—
The server echoes the data back and closes its side.reply = echo: hello
—
The client prints the reply.reply = echo: hello
echo: hello

Behind the scenes

How JavaScript processes this code

A JavaScript engine parses and runs the source. A function body runs when the function is called. console.log writes to the console.

Cost and common mistakes

O(m) for an m-byte message.

  • A single data event may contain part of a message or several messages. Buffer the bytes until a delimiter arrives.
  • Not closing the server leaves the process running forever. Close it once the client is finished.
  • Data arrives as Buffers. Convert with toString() or set an encoding before treating it as text.

Try it yourself

How would you let the server handle many clients?

Reveal answer and reasoning

Nothing extra is needed: createServer calls the handler for every connection, and each socket has its own events.

Further reading