search
HomeWeb Front-endJS TutorialA brief analysis of TCP and UDP in Node

A brief analysis of TCP and UDP in Node

Apr 20, 2023 pm 06:15 PM
javascriptfront endnode.js

A brief analysis of TCP and UDP in Node

Node is a network-oriented platform. It is event-driven, non-blocking, single-threaded and has good scalability, making it It is very lightweight and suitable for playing various roles in distributed networks.

Node provides net, dgram, http, http2, https and other modules are used to process TCP, UDP, HTTP, HTTPS respectively, suitable for both server and client .

Building TCP services

TCP Services are very common in network applications, and most of the current applications are based on TCP Built, its full name is Transmission Control Protocol, which belongs to the transport layer protocol in the OSI model. Many application layer protocols are built based on TCP, and the typical HTTP , SMTP, IMAP and other protocols. I won’t talk about TCP related knowledge points here. If you are interested, you can follow my Computer Network column to learn.

Create TCP server

After basically understanding the working principle of TCP, we can start to create a TCP The server side accepts network requests. The net module provides an asynchronous network API for creating TCP# based on stream ## or IPC server and client. [Related tutorial recommendations: nodejs video tutorial, Programming teaching]

Please look at the example below, we write it in the

server.js file The following code is as follows:

import net from "net";

const server = net.createServer((socket) => {
  socket.on("data", (data) => {
    console.log("监听到客户端的数据:", data.toString());
  });
  // 监听客户端断开连接事件
  socket.on("end", () => {
    console.log("客户端断开连接");
  });
  // 发送数据给客户端
  socket.end("over over over\n");
});

// 启动服务
server.listen(3000, () => {
  console.log("服务创建成功");
});

We can create a

TCP server through net.createServer(listener). The parameter of this function is the link event The listener for connection.

When we execute the file in the terminal,

The service is created successfully and the output is in the terminal.

nodemon .\server.js

Earlier we created a server through

net.createServer, then we use net.connect to create a client for session, the specific code is as follows As shown:

import net from "net";

const client = net.connect({ port: 3000 }, () => {
  client.write("今晚出去吃饭,收到请 over\n");
});
// 接收服务端的数据
client.on("data", (data) => {
  console.log("接收服务端的数据: ", data.toString());
  // 断开连接
  client.end();
});

// 断开连接
client.on("end", () => {
  console.log("断开连接");
});

We execute two files at this time, as shown below:

A brief analysis of TCP and UDP in Node

Next we have such an example, the specific code As shown in the figure below:

A brief analysis of TCP and UDP in Node

Please see the following animation for the specific running results:

A brief analysis of TCP and UDP in Node

On the client I use

client.write() has sent data multiple times, but only the data other than setTimeout is normal. The continuous data sent in setTimeout does not seem to be one every time. Instead of returning, they will be randomly merged and returned, and sticky packets will appear here.

TCP There are certain optimization strategies for small data packets in the network: Negle Algorithm, if only one byte of content is sent at a time without optimization, the network It will be filled with datagrams with only a very small amount of valid data, which will be a great waste of network resources. For this situation, this algorithm requires the data in the buffer to reach a certain amount or a certain time before sending it out, so the small data packet will be sent out by the buffer. Algorithms are combined to optimize the network. Although this optimization enables efficient use of the network, data may be delayed in sending.

In

Node, since TCP enables the Negle algorithm by default, you can call socket.setNoDelay(true) Remove the Negle algorithm so that write() can send data to the network immediately:

A brief analysis of TCP and UDP in Node##Close

Nagle

The algorithm is not always effective, because it completes the merging on the server side. TCP The received data will be stored in its own buffer first, and then the application will be notified to receive it. The application layer will be blocked due to network or other problems. The reason is that if the data cannot be retrieved from the TCP buffer in time, multiple data blocks will be stored in the TCP buffer, which will cause sticky packets.

TCP Principle

In

Node

, calling createServer() is equivalent to calling new Server() , the specific results are shown in the figure below:

这主要的原因它在 Node 源码中有如下定义,所以调用 createServer() 函数实际上调用的是 new Server(),具体代码如下图所示:

function createServer(options, connectionListener) {
  return new Server(options, connectionListener);
}

该构造函数的定义主要有如下所示:

function Server(options, connectionListener) {
  EventEmitter.call(this);
  // 注册连接到来时执行的回调
  if (typeof options === "function") {
    connectionListener = options;
    options = {};
    this.on("connection", connectionListener);
  } else if (options == null || typeof options === "object") {
    options = { ...options };

    if (typeof connectionListener === "function") {
      this.on("connection", connectionListener);
    }
  }
  // 服务器建立的连接数
  this._connections = 0;

  this[async_id_symbol] = -1;
  this._handle = null;
  this._usingWorkers = false;
  this._workers = [];
  this._unref = false;
  // 服务器下的所有连接是否允许半连接
  this.allowHalfOpen = options.allowHalfOpen || false;
  // 有连接时是否注册读事件
  this.pauseOnConnect = !!options.pauseOnConnect;
  this.noDelay = Boolean(options.noDelay);
  // 是否支持keepAlive
  this.keepAlive = Boolean(options.keepAlive);
  this.keepAliveInitialDelay = ~~(options.keepAliveInitialDelay / 1000);
}
ObjectSetPrototypeOf(Server.prototype, EventEmitter.prototype);
ObjectSetPrototypeOf(Server, EventEmitter);

listen

它返回的是一个普通的 JavaScript 对象,接着调用 listen 函数监听端口,listen 方法支持多种使用方式主要有以下这几种方法:

  • 传入的是一个已经创建的 TCP 服务器,而不是需要创建的一个服务器;
  • 传进来是一个对象,并且带了 fd 字段;
  • 创建了一个 TCP 服务器,并启动该服务器,如果传入了 host 会对其进行域名解析;

该方法的的主要逻辑有如下代码所示:

Server.prototype.listen = function (...args) {
  /*
         处理入参,根据文档我们知道listen可以接收好几个参数,
          假设我们这里是只传了端口号9297  
        */
  var normalized = normalizeArgs(args);
  //  normalized = [{port: 9297}, null];
  var options = normalized[0];
  var cb = normalized[1];
  // 第一次listen的时候会创建,如果非空说明已经listen过
  if (this._handle) {
    throw new errors.Error("ERR_SERVER_ALREADY_LISTEN");
  }
  // listen成功后执行的回调
  var hasCallback = cb !== null;
  if (hasCallback) {
    // listen成功的回调
    this.once("listening", cb);
  }

  options = options._handle || options.handle || options;
  // 第一种情况,传进来的是一个TCP服务器,而不是需要创建一个服务器
  if (options instanceof TCP) {
    this._handle = options;
    this[async_id_symbol] = this._handle.getAsyncId();
    listenIncluster(this, null, -1, -1, backlogFromArgs);
    return this;
  }
  // 第二种,传进来一个对象,并且带了fd
  if (typeof options.fd === "number" && options.fd >= 0) {
    listenIncluster(this, null, null, null, backlogFromArgs, options.fd);
    return this;
  }
  // 创建一个tcp服务器
  var backlog;
  if (typeof options.port === "number" || typeof options.port === "string") {
    backlog = options.backlog || backlogFromArgs;
    // 第三种 启动一个TCP服务器,传了host则先进行DNS解析
    if (options.host) {
      lookupAndListen(
        this,
        options.port | 0,
        options.host,
        backlog,
        options.exclusive
      );
    } else {
      listenIncluster(
        this,
        null,
        options.port | 0,
        4,
        backlog,
        undefined,
        options.exclusive
      );
    }
    return this;
  }
};

listenInCluster

在每种方式的最后丢回调用 listenIncluster 方法,该方法主要做的事情是区分 master 进程 和 worker 进程,采用不同的处理策略:

  • mastr 进程: 直接调用 server._listen 启动监听;
  • worker 进程: 使用 cluster._getServer 处理传入的 server 对象,修改 server._handle 再调用了 server._listen 启动监听;

构建 UDP 服务

UDP 又称用户数据包协议,与 TCP 一样同属于网络层传输层。UDPTCP 最大的不同是 UDP 不是面向链接的。

创建 <span style="font-size: 18px;">UDP</span> 服务

创建 UDP 套接字十分简单,UDP 套接字一旦创建,既可以作为客户端发送数据,也可以作为服务端接收数据,下面的代码创建了一个 UDP 套接字,具体代码如下所示:

import dgram from "node:dgram";

const server = dgram.createSocket("udp4");

server.on("error", (err) => {
  console.error(`server error:\n${err.stack}`);
  server.close();
});

server.on("message", (msg, rinfo) => {
  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});

server.on("listening", () => {
  const address = server.address();
  console.log(`server listening ${address.address}:${address.port}`);
});

server.bind(3000);

该套接字将接收所有网课上 3000 端口上的消息,在绑定完成后,将触发 listening 事件,会终端执行,会输出 server listening 0.0.0.0:3000 字段。

接下来我们创建一个客户端和服务端进行对话,具体代码如下所示:

import dgram from "node:dgram";
import { Buffer } from "node:buffer";

const message = Buffer.from("你个叼毛");
const client = dgram.createSocket("udp4");

client.send(message, 0, message.length, 3000, "localhost", () => {
  client.close();
});

终端的最终输出结果如下图所示

A brief analysis of TCP and UDP in Node

UDP 广播

dgram 模块中,可以使用 socket 端口对象的 setBroadcast 方法来进行数据的广播:

socket.setBroadcast(flag);
  • flag: 当 flagtrue 时,UDP 服务器或者客户端可以利用其所用的 socket 端口对象的 send 方法中的地址修改为广播地址。

服务端的代码定义在 server.js 文件,具体代码如下所示:

import dgram from "dgram";

const server = dgram.createSocket("udp4");

server.on("message", function (msg, rinfo) {
  console.log(
    "server got: " + msg + " from " + rinfo.address + ":" + rinfo.port
  );
});

server.on("listening", function () {
  var address = server.address();
  console.log("server listening " + address.address + ":" + address.port);
});

server.bind(3000);

客户端的代码定义在 server.js 文件,具体代码如下定义:

import dgram from "dgram";
import { Buffer } from "buffer";

const socket = dgram.createSocket("udp4");
const params = process.argv.splice(2);

socket.bind(function () {
  socket.setBroadcast(true);
});

const message = Buffer.from(...params);

socket.send(message, 0, message.length, 3000, "255.255.255.255", () => {
  socket.close();
});

具体运行效果如下图所示:

A brief analysis of TCP and UDP in Node

更多node相关知识,请访问:nodejs 教程

The above is the detailed content of A brief analysis of TCP and UDP in Node. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:掘金社区. If there is any infringement, please contact admin@php.cn delete
JavaScript Engines: Comparing ImplementationsJavaScript Engines: Comparing ImplementationsApr 13, 2025 am 12:05 AM

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

Beyond the Browser: JavaScript in the Real WorldBeyond the Browser: JavaScript in the Real WorldApr 12, 2025 am 12:06 AM

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Apr 11, 2025 am 08:23 AM

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)Apr 11, 2025 am 08:22 AM

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

JavaScript: Exploring the Versatility of a Web LanguageJavaScript: Exploring the Versatility of a Web LanguageApr 11, 2025 am 12:01 AM

JavaScript is the core language of modern web development and is widely used for its diversity and flexibility. 1) Front-end development: build dynamic web pages and single-page applications through DOM operations and modern frameworks (such as React, Vue.js, Angular). 2) Server-side development: Node.js uses a non-blocking I/O model to handle high concurrency and real-time applications. 3) Mobile and desktop application development: cross-platform development is realized through ReactNative and Electron to improve development efficiency.

The Evolution of JavaScript: Current Trends and Future ProspectsThe Evolution of JavaScript: Current Trends and Future ProspectsApr 10, 2025 am 09:33 AM

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.

Demystifying JavaScript: What It Does and Why It MattersDemystifying JavaScript: What It Does and Why It MattersApr 09, 2025 am 12:07 AM

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

Is Python or JavaScript better?Is Python or JavaScript better?Apr 06, 2025 am 12:14 AM

Python is more suitable for data science and machine learning, while JavaScript is more suitable for front-end and full-stack development. 1. Python is known for its concise syntax and rich library ecosystem, and is suitable for data analysis and web development. 2. JavaScript is the core of front-end development. Node.js supports server-side programming and is suitable for full-stack development.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

Atom editor mac version download

Atom editor mac version download

The most popular open source editor