1. Opening analysis
Starting today, let’s learn in detail in specific modules. This article is the third article in this series. The first two articles are mainly based on theory. I believe that in the study of the first two articles,
I also have a basic understanding of NodeJS, it's okay! ! ! Strike while the iron is hot, let's continue to carry NodeJS to the end. Well, without saying much nonsense, go directly to today's topic "Net module". So how should "Net" understand that?
What is it for? ( Net module can be used to create Socket servers or Socket clients. The two most basic modules for NodeJS data communication are Net and Http. The former is a Tcp-based encapsulation, while the latter is essentially a Tcp layer, but it has done a lot of data encapsulation, which we regard as a presentation layer).
Here we refer to the source code in NodeJS "http.js":
It is not difficult to see from the figure that HttpServer inherits the Net class, has related communication capabilities, and has done more data encapsulation, which we regard as a more advanced representation layer.
Extended knowledge (the following is the source code of "inherits"):
The code copy is as follows:
exports.inherits = function(ctor, superCtor) {
ctor.super_ = superCtor;
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
The function is to realize inheritance and reuse.
I just gave a brief overview, which contains some commonly used concepts. Here is a brief introduction to popularizing concepts:
(1) TCP/IP----------TPC/IP protocol is a transport layer protocol, which mainly solves how data is transmitted on the network.
(2), Socket-----socket is the encapsulation and application of the TCP/IP protocol (program level).
(3), Http------ HTTP is an application-layer protocol, which mainly solves how to wrap data.
(4) The seven-layer network model----------------------------------------------------------------------------------------------------------------------
To sum up: Socket is an encapsulation of the TCP/IP protocol. Socket itself is not a protocol, but a calling interface (API).
This forms some of the most basic functional interfaces we know, such as Create, Listen, Connect, Accept, Send, Read and Write, etc.
TCP/IP is just a protocol stack, just like the operating system's operating mechanism, it must be implemented in detail, and it also provides external operating interfaces.
In fact, the TCP of the transport layer is based on the IP protocol of the network layer, and the HTTP protocol of the application layer is based on the TCP protocol of the transport layer. Socket itself is not a protocol. As mentioned above, it only provides an interface for TCP or UDP programming.
Second, experience it
OK, we have the concept, let’s take an example:
1. Create server.js
The code copy is as follows:
var net = require('net') ;
var server = net.createServer(function(c) { // Connection listener
console.log("Server connected");
c.on("end", function() {
console.log("Server has been disconnected");
}) ;
c.write("Hello,Bigbear !/r/n");
c.pipe(c);
}) ;
server.listen(8124, function() { // Listening listener
console.log("server bound");
}) ;
2. Create client.js
The code copy is as follows:
var net = require('net') ;
var client = net.connect({
port: 8124
},function(){ // connect listener
console.log("Client connected");
client.write('Hello,Baby !/r/n') ;
});
client.on("data", function(data) {
console.log(data.toString());
client.end() ;
});
client.on("end", function(){
console.log("client disconnect");
}) ;
Let's analyze:
Server------ net.createServer creates a TCP service. This service is bound (server.listen) on the port 8124. After creating the Server, we see a callback function.
When calling the above function, a parameter is also a function, and it accepts socket, a pipe constructed by other methods, and its function is for data interaction.
pipe needs to be greeted by the Client to establish it. If there is no client access to the Server at this moment, this socket will not exist.
As the name suggests,客户端------net.connect is connected to the server. The first parameter is an object. The port (port) is set to 8124, which is the port that our server listens to. Since the host parameter is not set, the default is localhost (local).
In Server, the socket is one end of the pipeline, and in the client, the client itself is one end of the pipeline. If multiple clients are connected to the Server, the Server will create multiple sockets, and each socket corresponds to a client.
Running results:
3. Case introduction
(1) The following code is just the server outputting a piece of text to the client to complete one-way communication from the server to the client.
The code copy is as follows:
// Sever --> Client's one-way communication
var net = require('net');
var chatServer = net.createServer();
chatServer.on('connection', function(client) {
client.write('Hi!/n'); // The server outputs information to the client and uses the write() method
client.write('Bye!/n');
client.end(); // The server ends the session
});
chatServer.listen(9000);
Telnet test: telnet127.0.0.1:9000
After executing telnet, connect to the service point, feedback the characters of Hi! Bye!, and immediately end the server program and terminate the connection.
What if we want the server to connect to the information to the client?
You can listen to the server.data event and do not abort the connection (or it will immediately end messages from the client that cannot be accepted).
(2), listen to the server.data event and do not abort the connection (otherwise, messages from the client will be unable to be accepted immediately).
The code copy is as follows:
// Based on the former, implement Client --> Sever communication, which is two-way communication
var net = require('net');
var chatServer = net.createServer(),
clientList = [];
chatServer.on('connection', function(client) {
// JS can freely add properties to objects. Here we add a custom attribute of name to indicate which client (the address + port of the client is based on)
client.name = client.remoteAddress + ':' + client.remotePort;
client.write('Hi ' + client.name + '!/n');
clientList.push(client);
client.on('data', function(data) {
broadcast(data, client);// Accept information from the client
});
});
function broadcast(message, client) {
for(var i=0;i<clientList.length;i+=1) {
if(client !== clientList[i]) {
clientList[i].write(client.name + " says " + message);
}
}
}
chatServer.listen(9000);
Is the above a complete code? We said there is another problem that has not been taken into account: that is, once a client exits, it remains in the clientList, which is obviously a null pointer.
(3) Process clientList
The code copy is as follows:
chatServer.on('connection', function(client) {
client.name = client.remoteAddress + ':' + client.remotePort
client.write('Hi ' + client.name + '!/n');
clientList.push(client)
client.on('data', function(data) {
broadcast(data, client)
})
client.on('end', function() {
clientList.splice(clientList.indexOf(client), 1); // Delete the formula element in the array.
})
})
NodeTCPAPI has provided us with an end event, that is, when the client aborts the connection to the server.
(4) Optimize broadcast
The code copy is as follows:
function broadcast(message, client) {
var cleanup = []
for(var i=0;i<clientList.length;i+=1) {
if(client !== clientList[i]) {
if(clientList[i].writable) { // Check whether sockets are writable first
clientList[i].write(client.name + " says " + message)
} else {
cleanup.push(clientList[i]) // If it is not writable, collect and destroy it. Before destruction, Socket.destroy() should be destroyed by API.
clientList[i].destroy()
}
}
} //Remove dead Nodes out of write loop to avoid trashing loop index
for(i=0;i<cleanup.length;i+=1) {
clientList.splice(clientList.indexOf(cleanup[i]), 1)
}
}
Note that once "end" is not triggered, an exception will occur, so the optimization work will be done.
(5) NetAPI also provides an error event to catch client exceptions
The code copy is as follows:
client.on('error', function(e) {
console.log(e);
});
Four, let's summarize
1. Understand the relevant concepts of the beginning
2. Understand the relationship between Http and Net modules
3. Based on the examples in this article, please refer to the relevant APIs to practice.
4. Communication ideas between socket client and server
5. If you are interested, you can improve the example of that chat room