TCP сокеты в Node.js — модуль net

Низкоуровневая работа с TCP — клиент-серверная коммуникация через сырые сокеты, под капотом HTTP/WebSocket/SMTP.

Что это

net — встроенный модуль Node.js для TCP-сокетов (потоковый протокол с гарантией доставки и порядка). На нём построены http, https, ws. Прикладные протоколы (SMTP, FTP, Redis-протокол) часто пишут поверх net.

TCP-сокет в ноде — это duplex-стрим. Под одним сокетом одновременно работают read и write.

API / Пример

const net = require('net');

// Сервер
const server = net.createServer((socket) => {
  socket.write('hello\n');
  socket.on('data', (chunk) => console.log('client:', chunk.toString()));
  socket.on('end', () => console.log('client disconnected'));
  socket.on('error', (err) => console.error(err));
});
server.listen(2000, '0.0.0.0');

// Клиент
const client = new net.Socket;
client.connect(2000, 'localhost', () => client.write('hi\n'));
client.on('data', (chunk) => console.log('server:', chunk.toString()));

События сокета

  • lookup — DNS-резолв (только клиент)
  • connect — соединение установлено
  • data — пришёл Buffer
  • drain — внутренний буфер на запись опустел (для backpressure)
  • end — другая сторона отправила FIN
  • close — сокет полностью закрыт
  • error — ошибка резолва DNS или соединения
  • timeout — таймаут бездействия

Производительность / Подводные камни

  • Алгоритм Нейгла включён по умолчанию — буферизует мелкие пакеты. Для real-time выключают: socket.setNoDelay(true).
  • Открытый сокет держит процессsocket.unref позволяет завершиться, если он единственная причина жить.
  • ECONNRESET — клиент отвалился раньше, чем сервер дочитал. Всегда обрабатывать error, иначе процесс падает.
  • socket.remotePort выдаёт ОС — это handle для идентификации соединения (host+port).
  • UTF-8 в стриме — символ может прийти в двух чанках. Использовать StringDecoder.

🎓 Источники

  • 🎓 Клиент-сервер на Node.js TCP и UDP, DNS · 2018-10-03
    • Тезисы: модуль net для TCP; createServer принимает listener (socket) => {...}; алгоритм Нейгла буферизует; pause/resume для управления потоком; unref чтобы сокет не держал процесс.
    • Цитата: «Если делаем setNoDelay true — алгоритм Нейгла отключен, потому что буферизацией занимается он, встроенный в TCP/IP stack.»

См. также