当前位置:网站首页>Nodejs uses net module to create TCP server and client
Nodejs uses net module to create TCP server and client
2022-06-09 08:32:00 【Jieyou grocery store Q】
1、 Preface
Here I have to say TCP and websocket The difference between communication :
difference
according to OSI Network layered model ,IP It's network layer protocol ,TCP It's the transport layer protocol , and HTTP It's the application layer protocol . Between the three ,SPDY and WebSocket Are all with HTTP Related agreements , and TCP yes HTTP The underlying protocol .
WebSocket Then provide to use a TCP The mechanism of two-way communication through connection , Including network protocol and API, To replace web pages and servers with HTTP Polling is a mechanism for two-way communication .
In essence ,WebSocket It's not limited to HTTP Agreed , But because there are a lot of HTTP infrastructure , agent , Filter , Identity authentication and so on ,WebSocket To borrow HTTP and HTTPS The port of .
Due to the use HTTP The port of , therefore TCP The handshake message after the connection is established is based on HTTP Of , Judging by the server, this is a HTTP Agreement or WebSocket agreement .
WebSocket Except for the handshake when establishing and closing the connection , Data transmission and HTTP It doesn't matter at all .
In a word
websocket A handshake is established by http Of , The real transmission will not be carried out later HTTP Interaction , But the beginning websocket Data frame protocol for . Realize the data exchange between client and server
So use Nodejs Create a TCP What about servers? ?
2、 Fulfill the requirements
The server can send messages to clients in groups , It should also support directional sending of information
3、 Simple implementation of the server
net The module is Nodejs Built in basic network module , By using net, You can create a simple tcp The server
server.listen(port[,host][,backlog][,callback])
port The parameter is the port number to listen to , Parameter values for 0 A port number will be randomly assigned when .
host For server address .
backlog Is the maximum length of the waiting queue
callback Is the callback function
Callback events :
connection: Triggered when the current new link is created , The parameters of the callback function are socket Connection object , Same as net.createServer The second function parameter of .
close:TCP Triggered when the server shuts down , The callback function has no parameters
error:TCP Triggered when an error occurs on the server , The parameters of the callback function are error object
listening: call server.listen The callback triggered when
// introduce NET
const net = require('net');
// establish TCP The server
const server = net.createServer(function (client) {
console.log('someones connects');
// Receiving data from clients
client.on('data', function (data) {
setTimeout(() => {
client.write(' The server sends a notification ');
}, 3000);
console.log(' The server receives data from the client :', data.toString('utf-8'));
});
// Client connection closed
client.on('close', function (err) {
console.log(' Client offline ');
});
// Client connection error
client.on('error', function (err) {
console.log(' Client connection error ');
});
});
// Listen for client connections
server.listen(
{
port: 9001,
host: '127.0.0.1',
},
function () {
console.log('server start listening');
}
);
// Set the callback function during listening
server.on('listening', function () {
const {
address, port } = server.address();
console.log('server is running: ' + address + ':' + port);
});
// Set the callback function when closing
server.on('close', function () {
console.log('sever closed');
});
// Set the callback function in case of error
server.on('error', function () {
console.log('sever error');
});
4、 Simple client implementation
const net = require('net');
const sock = net.connect(
{
port: 9001,
host: '127.0.0.1',
},
function () {
console.log('connected to server!');
}
);
// Successful connection
sock.on('connect', function () {
console.log('connect success');
// Send data to the server
sock.write(" Test data ", 'utf8');
});
// Receive information from the server
sock.on('data', function (data) {
console.log(' Received the information from the server :', data.toString('utf-8'));
});
// An error occurs in the calling event
sock.on('error', function (e) {
console.log('socket error', e);
});
// socket Closed Events
sock.on('close', function () {
console.log('socket close');
});
// The other party sent an event to close the packet
sock.on('end', function () {
console.log('socket end');
});



5、 Logic implementation
The simple example above , The group sending function has been realized , After the server sends a message , All connected clients can receive messages .
What if you send a message one-to-one ?
Because each connection between client and server does not have an alias , We can only get the client's IP and PORT,So we simply put IP+PORT Spliced as SessionId As the only one ID,
Return to all Client Instances are stored
// Custom client connections SESSIONID
const {
remoteAddress, remotePort } = client;
client.name = `${
remoteAddress}:${
remotePort}`;
/** * Storage client , One to many , Or one-on-one , radio broadcast * clients = [{name: Client alias , sessionId: Unique session ID,client: Client connection instance }] **/
const clients = [];
// Storage
function storeClient(client, name = '') {
if (!client || !client.remoteAddress || !client.remotePort) return;
const {
remoteAddress, remotePort } = client;
const sessionId = `${
remoteAddress}:${
remotePort}`;
const existClient = clients.find(m => m.sessionId == sessionId);
// If it doesn't exist , Storage instance
if (!existClient) {
clients.push({
name,
sessionId,
client,
});
} else {
// If there is , to update
existClient.client = client;
existClient.name = name;
}
}
What if the server wants to send messages through an alias , What to do ?
The client can connect successfully at the first time , Synchronize alias to server, So the server knows the alias of the client
// The event of successful connection invocation
sock.on('connect', function () {
console.log('connect success');
// Synchronization server , Basic client information
const info = {
type: 'sync',
clientName: 'Client-1',
message: ' Synchronize basic information ',
};
const message = `${
info.clientName} Synchronize the basic information to the server ${
info.message}`;
sock.write(JSON.stringify(info), 'utf8');
});
6、 Complete code
Server side
const net = require('net');
/** * Storage client , One to many , Or one-on-one , radio broadcast * clients = [{name: Client alias , sessionId: Unique session ID,client: Client connection instance }] **/
const clients = [];
// establish
const server = net.createServer(function (client) {
// Custom client connections SESSIONID
// Or it can be defined on the client side UUID, Synchronize information
const {
remoteAddress, remotePort } = client;
client.name = `${
remoteAddress}:${
remotePort}`;
// Storage
storeClient(client);
console.log('[ The client has accessed ]: ', client.name);
console.log(
'[ All clients that have been connected at present ]: ',
clients.map(m => m.sessionId)
);
// Listen for data from the client
client.on('data', function (data) {
try {
// Be sure to constrain the fixed message template , here data The agreement is JSON Formatted data
const _data = JSON.parse(data);
const {
type, clientName, message } = _data;
if (type == 'sync') {
// Sync information
storeClient(client, clientName);
} else if (type == 'info') {
// Message exchange
}
console.log(
' The server receives a message from the client ' + client.name + ' The data of ',
message.toString('utf-8')
);
} catch (error) {
}
});
// Handle when the client disconnects ,
// Prompt the user to disconnect and leave , Delete client connection pool
client.on('close', function () {
const index = clients.findIndex(m => m.sessionId == client.name);
if (index >= 0) clients.splice(index, 1);
console.log(
'【all clients】',
clients.map(m => m.sessionId)
);
console.log(client.name, ' Get offline ');
});
// Client connection error
client.on('error', function (err) {
console.log(client.name + ' Connection error ', err);
});
});
// radio broadcast
const broadcast = ({
clientName, message }) => {
// Directional broadcast
if (clientName) {
const client = clients.find(m => m.name == clientName);
client && client.client.write(message);
} else {
// Mass hair
clients.map(m => {
m.client.write(message);
});
}
};
// test
let testTimeout = null;
server.on('connection', function () {
clearTimeout(testTimeout);
testTimeout = setTimeout(() => {
console.log(' Inform everyone : I'm here to get supplies ');
broadcast({
message: '\n\r We have come to collect supplies ' });
console.log(' notice Client-1: Hurry to make nucleic acid , Everything is waiting for you ');
broadcast({
clientName: 'Client-1', message: '\n\r Hurry to make nucleic acid , Everything is waiting for you ' });
console.log(' notice Client-2: Come and do nucleic acid later ');
broadcast({
clientName: 'Client-2', message: '\n\r Come and do nucleic acid later ' });
}, 10000);
});
server.on('listening', function () {
console.log(' Waiting for the connection ...');
});
// Port listening
server.listen({
port: 9000,
host: '127.0.0.1',
});
// Call when listening for errors
server.on('error', function () {
console.log('listen error');
});
server.on('close', function () {
console.log('server stop listener');
});
// Storage
function storeClient(client, name = '') {
if (!client || !client.remoteAddress || !client.remotePort) return;
const {
remoteAddress, remotePort } = client;
const sessionId = `${
remoteAddress}:${
remotePort}`;
const existClient = clients.find(m => m.sessionId == sessionId);
// If it doesn't exist , Storage instance
if (!existClient) {
clients.push({
name,
sessionId,
client,
});
} else {
// If there is , to update
existClient.client = client;
existClient.name = name;
}
}
client Client-1
const net = require('net');
// net.Socket,
const sock = net.connect(
{
port: 9000,
host: '127.0.0.1',
},
function () {
console.log('connected to server!');
}
);
// The event of successful connection invocation
sock.on('connect', function () {
console.log('connect success');
// Synchronization server , Basic client information
const info = {
type: 'sync',
clientName: 'Client-1',
message: ' Synchronize basic information ',
};
const message = `${
info.clientName} Synchronize the basic information to the server ${
info.message}`;
console.log(message);
sock.write(JSON.stringify(info), 'utf8');
// Delay sending data
setTimeout(() => {
// The message template
const info = {
type: 'info',
clientName: 'Client-1',
message: '1111',
};
const message = `${
info.clientName} Send information to the server :${
info.message}`;
console.log(message);
sock.write(JSON.stringify(info), 'utf8');
}, 3000);
});
// When data occurs , call ;
sock.on('data', function (data) {
console.log('Client-1 Received the information from the server :', data.toString('utf-8'));
});
// An error occurs in the calling event
sock.on('error', function (e) {
console.log('error', e);
});
// socket Closed Events
sock.on('close', function () {
console.log('close');
});
// The other party sent an event to close the packet
sock.on('end', function () {
console.log('end');
});
client Client-2
const net = require('net');
// net.Socket,
const sock = net.connect(
{
port: 9000,
host: '127.0.0.1',
},
function () {
console.log('connected to server!');
}
);
// The event of successful connection invocation
sock.on('connect', function () {
console.log('connect success');
// Synchronization server , Basic client information
const info = {
type: 'sync',
clientName: 'Client-2',
message: ' Synchronize basic information ',
};
const message = `${
info.clientName} Synchronize the basic information to the server ${
info.message}`;
console.log(message);
sock.write(JSON.stringify(info), 'utf8');
// Delay sending data
setTimeout(() => {
// The message template
const info = {
type: 'info',
clientName: 'Client-2',
message: '222',
};
const message = `${
info.clientName} Send information to the server :${
info.message}`;
console.log(message);
sock.write(JSON.stringify(info), 'utf8');
}, 3000);
});
// When data occurs , call ;
sock.on('data', function (data) {
console.log('Client-2 Received the information from the server :', data.toString('utf-8'));
});
// An error occurs in the calling event
sock.on('error', function (e) {
console.log('error', e);
});
// socket Closed Events
sock.on('close', function () {
console.log('close');
});
// The other party sent an event to close the packet
sock.on('end', function () {
console.log('end');
});



边栏推荐
猜你喜欢
![[pat (basic level) practice] - [sort] 1077 mutual evaluation score calculation](/img/0c/f9deb9b02936e1fc2a53ef3e44c6bf.jpg)
[pat (basic level) practice] - [sort] 1077 mutual evaluation score calculation

About Eigendecomposition

自制编译器学习4:使用Flex

RMAN备份概念_关于备份集(Backup Set)

Yyds dry goods sharing # master this Q version of figure painting method, and you can finish the avatar for one month at a time!

Puzzle (105) plane inversion

English语法_副词

About Eigendecomposition

Question about Oracle: why can't the DBMS be linked according to the evening tutorial and output results

JVM体系架构学习笔记
随机推荐
Out object of JSP development details you should know (I)
English语法_方式副词
Self made compiler learning 2: compilation process
MySQL查询数据库所有表名及其注释
OpenInfra Summit 2022 | 安超云用户脱颖而出 入围超级用户大奖
Nacos二次开发
2022-2028 global nonlinear node detector industry survey and trend analysis report
SQL: 股票的资本损益
业务判断逻辑代码 if 语句
JVM architecture learning notes
2022-2028 global TSCM equipment industry research and trend analysis report
2022-2028 global Supplementary Cementitious Materials (SCM) industry research and trend analysis report
Nacos 启动报错[db-load-error]load jdbc.properties error
EDA open source simulation tool verilator getting started 1: installation and testing
Market Research - current market situation and future development trend of cosmetic grade ethylhexyl glycerol in the world and China
Leetcode: find the number of recent palindromes
Market Research - current situation and future development trend of global and Chinese sunfish feed market
2022-2028 global anti UAV (c-uas) technology industry research and trend analysis report
Open source EDA software yosys for integrated circuit design 1: tool installation
Go questions / knowledge gathering - 2