1. Análisis de apertura
A partir de hoy, aprendamos en detalle en módulos específicos. Este artículo es el tercer artículo de esta serie. Los dos primeros artículos se basan principalmente en la teoría. Creo que en el estudio de los dos primeros artículos,
También tengo una comprensión básica de NodeJS, ¡está bien! ! ! Golpe mientras el hierro esté caliente, continuemos llevando NodeJs al final. Bueno, sin decir muchas tonterías, vaya directamente al tema "Módulo de red" de hoy. Entonces, ¿cómo debería "net" entender eso?
¿Para qué es? ( Net se puede usar para crear servidores de socket o clientes de socket. Los dos módulos más básicos para la comunicación de datos de NodeJS son netos y http. El primero es una encapsulación basada en TCP, mientras que los segundos es esencialmente una capa de TCP, pero ha hecho una encapsulación de datos, que consideramos una capa de presentación).
Aquí nos referimos al código fuente en NodeJS "http.js":
No es difícil ver en la figura que httpserver hereda la clase neta, tiene capacidades de comunicación relacionadas y ha hecho más encapsulación de datos, que consideramos una capa de representación más avanzada.
Conocimiento extendido (el siguiente es el código fuente de "heredes"):
La copia del código es la siguiente:
exports.inherits = function (ctor, superctor) {
ctor.super_ = superctor;
ctor.prototype = object.create (superctor.prototype, {
Constructor: {
Valor: CTOR,
enumerable: falso,
WRATITY: verdadero,
configurable: verdadero
}
});
};
La función es realizar la herencia y la reutilización.
Acabo de dar una breve descripción, que contiene algunos conceptos de uso común. Aquí hay una breve introducción a los conceptos populares:
(1) TCP/IP ---------- El protocolo TPC/IP es un protocolo de capa de transporte, que resuelve principalmente cómo se transmiten los datos en la red.
(2), Socket ----- Socket es la encapsulación y la aplicación del protocolo TCP/IP (nivel de programa).
(3), HTTP ------ HTTP es un protocolo de capa de aplicación, que resuelve principalmente cómo envolver datos.
(4) El modelo de red de siete capas ----------------------------------------------------------------------------------------------------------------------
Para resumir: el socket es una encapsulación del protocolo TCP/IP. El socket en sí no es un protocolo, sino una interfaz de llamada (API).
Esto forma algunas de las interfaces funcionales más básicas que conocemos, como crear, escuchar, conectar, aceptar, enviar, leer y escribir, etc.
TCP/IP es solo una pila de protocolo, al igual que el mecanismo operativo del sistema operativo, debe implementarse en detalle y también proporciona interfaces operativas externas.
De hecho, el TCP de la capa de transporte se basa en el protocolo IP de la capa de red, y el protocolo HTTP de la capa de aplicación se basa en el protocolo TCP de la capa de transporte. El socket en sí no es un protocolo. Como se mencionó anteriormente, solo proporciona una interfaz para la programación TCP o UDP.
Segundo, experiméntalo
Ok, tenemos el concepto, tomemos un ejemplo:
1. Crear servidor.js
La copia del código es la siguiente:
var net = require ('net');
var servidor = net.createServer (función (c) {// Eyeer de conexión
console.log ("Servidor conectado");
c.on ("end", function () {
console.log ("el servidor se ha desconectado");
});
c.write ("Hola, Bigbear!/R/N");
C. tupe (c);
});
server.listen (8124, function () {// escucha oyente
console.log ("Server Bound");
});
2. Crea client.js
La copia del código es la siguiente:
var net = require ('net');
var client = net.connect ({
Puerto: 8124
}, function () {// conectar el oyente
console.log ("Cliente conectado");
Client.write ('¡Hola, bebé!/r/n');
});
client.on ("data", function (data) {
console.log (data.toString ());
Client.end ();
});
client.on ("end", function () {
console.log ("Desconectación del cliente");
});
Analicemos:
Servidor ------ net.createServer crea un servicio TCP. Este servicio está vinculado (server.listen) en el puerto 8124. Después de crear el servidor, vemos una función de devolución de llamada.
Al llamar a la función anterior, un parámetro también es una función, y acepta el socket, una tubería construida por otros métodos, y su función es para la interacción de datos.
La tubería debe ser recibida por el cliente para establecerlo. Si no hay acceso al cliente al servidor en este momento, este socket no existirá.
Como su nombre indica,客户端------net.connect está conectado al servidor. El primer parámetro es un objeto. El puerto (puerto) se establece en 8124, que es el puerto al que nuestro servidor escucha. Dado que el parámetro del host no está configurado, el valor predeterminado es localhost (local).
En el servidor, el socket es un extremo de la tubería, y en el cliente, el cliente en sí es un extremo de la tubería. Si se conectan varios clientes al servidor, el servidor creará múltiples sockets y cada socket corresponde a un cliente.
Resultados de ejecución:
3. Introducción del caso
(1) El siguiente código es solo el servidor que genera un texto al cliente para completar la comunicación unidireccional desde el servidor al cliente.
La copia del código es la siguiente:
// sever-> comunicación unidireccional del cliente
var net = require ('net');
var chatserver = net.createServer ();
chatserver.on ('conexión', function (cliente) {
Client.write ('HI!/N'); // El servidor genera información al cliente y usa el método Write ()
Client.write ('Bye!/n');
Client.end (); // El servidor termina la sesión
});
chatserver.listen (9000);
Prueba de Telnet: Telnet127.0.0.1: 9000
Después de ejecutar Telnet, conéctese al punto de servicio, ¡comenta los caracteres de HI! Adiós!, E inmediatamente finalice el programa del servidor y termine la conexión.
¿Qué pasa si queremos que el servidor se conecte a la información al cliente?
Puede escuchar el evento servidor.data y no abortar la conexión (o finalizará inmediatamente los mensajes del cliente que no se pueden aceptar).
(2), escuche el evento servidor.data y no aborte la conexión (de lo contrario, los mensajes del cliente no podrán ser aceptados de inmediato).
La copia del código es la siguiente:
// Basado en el primero, implementar el cliente-> Comunicación severa, que es una comunicación bidireccional
var net = require ('net');
var chatserver = net.createServer (),
ClientList = [];
chatserver.on ('conexión', function (cliente) {
// JS puede agregar libremente propiedades a los objetos. Aquí agregamos un atributo personalizado de nombre para indicar en qué cliente (la dirección + puerto del cliente se basa)
client.name = client.remoteaddress + ':' + client.remoteport;
Client.Write ('Hi' + Client.name + '!/n');
ClientList.push (Cliente);
client.on ('data', function (data) {
transmitir (datos, cliente); // Aceptar información del cliente
});
});
Function Broadcast (Mensaje, Cliente) {
para (var i = 0; i <clientList.length; i+= 1) {
if (Client! == ClientList [i]) {
ClientList [i] .Write (Client.name + "dice" + mensaje);
}
}
}
chatserver.listen (9000);
¿El código completo es un código completo? Dijimos que hay otro problema que no se ha tenido en cuenta: es decir, una vez que un cliente sale, permanece en la lista de clientes, que obviamente es un puntero nulo.
(3) Procesar la lista de clientes
La copia del código es la siguiente:
chatserver.on ('conexión', function (cliente) {
client.name = client.remoteaddress + ':' + client.remoteport
Client.Write ('Hi' + Client.name + '!/n');
ClientList.push (cliente)
client.on ('data', function (data) {
transmitir (datos, cliente)
})
client.on ('end', function () {
ClientList.splice (ClientList.Indexof (Cliente), 1); // Eliminar el elemento de fórmula en la matriz.
})
})
Nodetcpapi nos ha proporcionado un evento final, es decir, cuando el cliente aborta la conexión al servidor.
(4) optimizar la transmisión
La copia del código es la siguiente:
Function Broadcast (Mensaje, Cliente) {
VAR Cleanup = []
para (var i = 0; i <clientList.length; i+= 1) {
if (Client! == ClientList [i]) {
if (clientList [i] .writable) {// verifique si los sockets son escritos primero
ClientList [i] .write (Client.name + "dice" + mensaje)
} demás {
Cleanup.push (ClientList [i]) // Si no es escritura, recogerlo y destruirlo. Antes de la destrucción, Socket.destroy () debe ser destruido por API.
ClientList [i] .destroy ()
}
}
} // eliminar los nodos muertos del bucle de escritura para evitar el índice de bucle de basura
para (i = 0; i <cleanup.length; i+= 1) {
ClientList.splice (ClientList.Indexof (Cleanup [i]), 1)
}
}
Tenga en cuenta que una vez que el "final" no se active, se producirá una excepción, por lo que se realizará el trabajo de optimización.
(5) NetAPI también proporciona un evento de error para atrapar las excepciones del cliente
La copia del código es la siguiente:
client.on ('error', function (e) {
console.log (e);
});
Cuatro, resumamos
1. Comprender los conceptos relevantes del principio
2. Comprender la relación entre HTTP y los módulos netos
3. Basado en los ejemplos de este artículo, consulte las API relevantes para practicar.
4. Ideas de comunicación entre el cliente de Socket y el servidor
5. Si está interesado, puede mejorar el ejemplo de esa sala de chat