vscodeの基盤となるipc通信はnodeモジュールをベースに
net
カプセル化されていますが、今日はnetモジュールの使い方を大まかに説明します。
公式ドキュメントのアドレス: https://nodejs.cn/api/net.html
ネットモジュールの役割
net モジュールは、ストリームベースの方法でサーバーとクライアントtcp
を構築する機能を提供します。ipc
TCP
node:net モジュールは、ストリームベースまたはIPCサーバー ( net.createServer() ) およびクライアント ( net.createConnection() )を作成するための非同期ネットワーク API を提供します。
TCP と IPC の概要
OSI 参照モデルは、ネットワーク通信機能を物理層、データリンク層、ネットワーク層、トランスポート層、セッション層、プレゼンテーション層、アプリケーション層の 7 層に分割します。TCP プロトコルはトランスポート層のプロトコルです。
TCP
TCP: 伝送制御プロトコル。同じマシン、異なるマシン、または異なるオペレーティング システム上のプロセス間で通信できます。
TCP 機能
- 接続指向
コネクション指向: 正式な通信の前に相手とのコネクションを確立する必要があることを意味し、いわゆる 3 ウェイ ハンドシェイクとも呼ばれます。
3 ウェイ ハンドシェイクの主な目的は、データ パケットの送受信を同期させることです。
スリーウェイ ハンドシェイクの一般的なプロセス: 1. クライアント A がホスト B に接続要求パケットを送信します; 2. ホスト B が接続と同期要求に同意するパケットをクライアント A に送信します; 3. クライアント A が確認するために別のパケットを送信します。ホスト B の同期。
-
端から端まで
-
信頼性のある
- アプリケーション データは、TCP が送信するのに最も適切であると判断したデータのチャンクにセグメント化されます。
- TCP はメッセージ セグメントを送信するときにタイマーを開始し、宛先がメッセージ セグメントの受信を確認するのを待ちます。時間内に確認を受信できない場合は、メッセージ セグメントを再送信します。
- TCP は、TCP 接続の相手側からデータを受信すると、確認応答を送信します。この確認はすぐには送信されず、延期されます。
- TCP はヘッダーとデータのチェックサムを維持します。これは、転送中のデータの変更を検出するためのエンドツーエンドのチェックサムです。受信したセグメントのチェックサムが正しくない場合、TCP はセグメントを破棄し、送信者がセグメントを再送信することを期待します。
- TCP セグメントは IP パケットとして送信され、IP データグラムが順序どおりに到着しない可能性があるため、TCP セグメントも順序どおりに到着しない可能性があります。必要に応じて、TCP は受信データの順序を変更します。受信データは正しい順序でアプリケーション層に渡されます。注文。ただし、IP データグラムは重複するため、TCP の受信側は重複したデータを破棄します。
- TCP はフロー制御も実行できます。TCP 接続の各パーティには固定サイズのバッファ スペースがあり、TCP 受信者は相手の送信者に受信者のバッファに収まるデータの送信のみを許可します。
IPC
IPC: (プロセス間通信) はプロセス間通信であり、同じマシン上の異なるプロセス間でのみ通信でき、物理マシンを越えることはできません。
TCPサーバーを構築する
TCP サーバーとクライアントの間でセッションを作成する過程で、サーバーとクライアントはそれぞれソケット (ソケット) を提供し、これら 2 つのソケットが一緒に接続を形成します。サーバーとクライアントはソケットを介して両者間の接続操作を実現します。
net.createServer([オプション][, connectListener])
-
オプション: オブジェクト
-
alloHalfOpen: ブール値、デフォルトは false です。読み取り可能な端が終了すると、ソケットは書き込み可能な端を自動的に終了します。
-
PauseOnConnect: ブール値、デフォルトは false、受信接続時にソケットを一時停止するかどうかを示します。
-
connectLisetener: クライアントがサーバーとの接続を確立するときのコールバック関数である関数。このコールバック関数はパラメータとしてソケット ポート オブジェクトを取ります。
-
ネットサーバーを返す
import net from 'net';
const server = net.createServer((socket) => {
console.log('client connect')
/***********************net.Socket事件*******************************/
// 接收到数据时触发。
socket.on('data', (data) => {
console.log(data.toString())
})
// 当成功建立套接字连接时触发。
socket.on('connect', () =>{
console.log('套接字建立成功')
})
// 当写缓冲区变空时触发。
socket.on('drain', () => {
})
// 当套接字的另一端表示传输结束时触发,从而结束套接字的可读端。
socket.on('end', () => {
console.log('数据接受完毕')
})
// 发生错误时触发,close事件将在此事件之后直接调用
socket.on('error', (err) => {
console.log(err)
})
// 一旦套接字完全关闭就触发
socket.on('close', (hasError) => {
// 参数 hadError 是布尔值,表示套接字是否由于传输错误而关闭。ture则表示由于传输错误而导致关闭
})
})
/***************************net.Server 属性*****************************/
// 最大连接数字,设置此属性以在服务器的连接计数变高时拒绝连接。
server.maxConnections = 6;
/***************************net.Server事件******************************/
// 建立新连接时触发
server.on('connection', (socket) => {
})
// 发生错误时触发
server.on('error', (err) => {
})
// 服务器关闭时触发
server.on('close', () => {
})
/****************************net.Server方法*******************************/
// 异步获取服务器上的并发连接数
server.getConnections((err, count) => {
if (err) return
console.log(count)
})
// 获取监听地址端口参数信息
const address = server.address();
// 绑定监听端口
server.listen(8124, () => {
console.log('TCP Server is runing')
})
// 停止服务器接受新连接并保持现有连接。
server.close((err) => {
// 该函数是异步的,当所有连接都结束并且服务器触发 'close' 事件时,则服务器最终关闭。
// 如果服务器在关闭时未打开,它将以 Error 作为唯一参数被调用。
})
TCPクライアントを構築する
net.createConnection()
import net from 'net';
// 创建新的 net.Socket,并立即使用 socket.connect() 发起连接,然后返回启动连接的 net.Socket。
// 建立连接后,将在返回的套接字上触发 'connect' 事件。 最后一个参数 connectListener(如果提供)将作为 'connect' 事件的监听器添加一次。
const client = net.createConnection({
port: 8124, // 端口
host: '11.11.11.12', // 服务地址,默认localhost
}, () => {
console.log('连接成功')
})
/*********************net.Socket 属性*************************/
// 接受的字节数
client.bytesRead = 1024;
// 发送的字节数
client.bytesWritten = 2048;
// 返回本地IP地址的字符串表示
client.localAddress
// 返回本地端口
client.localPort
// 远程 IP 地址的字符串表示形式
client.remoteAddress
// 远程 IP 系列的字符串表示形式。 'IPv4' 或 'IPv6'。
client.remoteFamily
// 远程端口的数字表示
client.remotePort
/*********************net.Socket 事件*************************/
// 连接server成功后触发
client.on('connect', () => {
})
// 接收到数据时触发
client.on('data', (data) => {
console.log(data.toString())
})
// 当套接字的另一端表示传输结束时触发,从而结束套接字的可读端。
client.on('end', () => {
})
// 当写缓冲区变空时触发。 可用于限制上传。
client.on('drain', () => {
})
// 当套接字准备好使用时触发。
client.on('ready', () => {
})
// 如果套接字因不活动而超时则触发。
client.on('timeout', () => {
// 这只是通知套接字已空闲。 用户必须手动关闭连接。
client.destroy() // 关闭连接
})
// 发生错误时触发。 'close' 事件将在此事件之后直接调用。
client.on('error', (err) => {
console.log(err)
})
/*********************net.Socket 方法********************************/
// 销毁流并关闭连接。
client.destroy()
// 在给定的套接字上发起连接。
client.connect()
// 获取连接地址信息
client.address()
// 关闭socket,可传入数据,在关闭之前再write一次数据
client.end(data, () => {
console.log('连接已关闭')
})
// 暂停读取数据
client.pause()
// 继续读取数据
client.resume()
// 为data事件中的datastream统一设置编码
client.setEncoding('utf8');
// 设置套接字超时事件
client.setTimeout(3000);
// 在套接字上发送数据。 第二个参数指定字符串情况下的编码。 它默认为 UTF8 编码。
client.write(data, (err) => {
if (err) return;
console.log('数据发送成功')
})