zoukankan      html  css  js  c++  java
  • 《深入浅出Node.js》第7章 网络编程

    @by Ruth92(转载请注明出处)

    第7章 网络编程

    Node 只需要几行代码即可构建服务器,无需额外的容器。

    Node 提供了以下4个模块(适用于服务器端和客户端):

    • net -> TCP
    • dgram -> UDP
    • http -> HTTP
    • https -> HTTPS

    OSI 模型:由七层组成,分别为物理层、数据链路层、网络层、传输层、表示层、应用层。

    图7-1 OSI模型(七层协议)

    一、构建 TCP 服务

    1. TCP

      TCP(传输控制协议),属于传输层协议,是面向连接的协议。

      许多应用层协议基于 TCP 构建,典型的是 HTTP、SMTP、IMAP 等协议。

      【显著特征】:在传输之前需要3次握手形成会话。

      • 只有会话形成之后,服务器端和客户端之间才能互相发送数据

      • 在创建会话的过程中,服务器端和客户端分别提供一个套接字,这两个套接字共同形成一个连接。

      • 服务器端与客户端则通过套接字实现两者之间连接的操作。

    2. 创建 TCP 服务器端

      TCP-Server.js

       var net = require('net');
       
       var server = net.createServer(function(socket) {
           // 新的连接
           socket.on('data', function(data) {
               socket.write('你好');
           });
       
           socket.on('end', function() {
               console.log('连接断开');
           });
       
           socket.write('欢迎光临《深入浅出Node.js》示例:
      ');
       });
       
       server.listen(8124, function() {
           console.log('server bound');
       });
      

      或者:

       var server = net.createServer();
       server.on('connection', function(socket) {
       	// 新的连接
       });
       server.listen(8124);
      

      TCP-Client.js

      通过 net 模块自行构造客户端进行会话,测试上面构建的TCP服务

       var client = net.connect({
           port: 8124
       }, function() { // 'connect' listener
           console.log('client connected');
           client.write('world!
      ');
       });
       
       client.on('data', function(data) {
           console.log(data.toString());
           client.end();
       });
       
       client.on('end', function() {
           console.log('client disconnected');
       });
      

      输出:

       client connected
       欢迎光临《深入浅出Node.js》示例:
      
       你好
       client disconnected
      
    3. TCP 服务的事件

      (1)服务器事件: listeningconnectioncloseerror

      (2)连接事件: dataendconnectdrainerrorclosetimeout

      注意,TCP针对网络中的小数据包有一定的优化策略:Nagle算法(默认),可以调用 socket.setNoDelay(true) 去掉 Nagle 算法,使得 write() 可以立即发送数据到网络中。

    二、构建 UDP 服务

    UDP:用户数据包协议,与 TCP 一样同属于网络传输层。

    UDP 与 TCP 的最大区别:

    (1) TCP 中连接一旦建立,所有会话都基于连接完成,客户端如果要与另一个TCP服务通信,需要另创建一个套接字来完成连接;

    (2)UDP 不是面向连接的,可以与多个 UDP 服务通信,提供面向事务的简单不可靠信息传输服务。

    缺点:在网络差的情况下丢包严重;

    优点:无须连接,资源消耗低,处理快速且灵活;

    应用:音频、视频等,及 DNS 服务。

    1. 创建 UDP 套接字

      UDP 套接字一旦创建,既可以作为客户端发送数据,也可以作为服务端接收数据。

       var dgram = require('dgram');
       var socket = dgram.createSocket('udp4');
      
    2. 创建 UDP 服务器端

       var dgram = require('dgram');
       var 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);
       });
       
       // 调用 dgram.bind(port, [address]) 方法对网卡和端口进行绑定
       // 该套接字将接收所有网卡上 41234 端口上的消息
       server.bind(41234);
      
    3. 创建 UDP 客户端

       var dgram = require('dgram');
       var message = new Buffer('深入浅出Node.js');
       var client = dgram.createSocket('udp4');
       
       // send() 方法:socket.send(buf, offset, length, port, address, [callback]);
       client.send(message, 0, message.length, 41234, 'localhost', function(err, bytes) {
           client.close();
       });
      
    4. UDP 套接字事件

      messagelisteningcloseerror

    三、构建 HTTP 服务

    如果要构造高效的网络应用,应该从传输层(TCP/UDP)进行着手,但是对于经典的应用场景,应用层协议绰绰有余。

    var http = require('http');
    
    http.createServer(function(req, res) {
        res.writeHead(200, {
            'Content-Type': 'text/plain'
        });
        res.end('Hello World
    ');
    }).listen(1337, '127.0.0.1');
    
    console.log('Server running at http://127.0.0.1:1337/');
    
    1. HTTP

      浏览器,其实是一个 HTTP 的代理。

      HTTP 服务只做两件事情:处理 HTTP 请求和发送 HTTP 响应。

    2. http 模块

      图7-4 http模块产生请求的流程

      http 模块将连接所有套接字的读写抽象为 ServerRequestServerResponse 对象,它们分别对应请求和响应操作。

      HTTP 请求:

      报文头部会通过 http_parser 进行解析。

      HTTP 响应:

      影响响应报文头部信息的 API:res.setHeader()res.writeHead()

      报文体部分调用:res.write()res.end()

      注意:无论服务器端在处理业务逻辑时是否发生异常,务必在结束时调用 res.end() 结束请求,否则客户端将一直处于等待的状态。当然,也可以通过延迟 res.end() 的方式实现客户端与服务器端之间的长连接,但结束时务必关闭连接。

      HTTP 服务的事件

      connectionrequestclosecheckContinueconnectupgradeclientError

    3. HTTP 客户端

       var http = require('http');
       
       var options = {
           hostname: '127.0.0.1',
           port: 1337,
           path: '/',
           method: 'GET'
       };
       
       var req = http.request(options, function(res) {
           console.log('STATUS: ' + res.statusCode);
           console.log('HEADERS: ' + JSON.stringify(res.headers));
           res.setEncoding('utf8');
           res.on('data', function(chunk) {
               console.log(chunk);
           });
       });
       
       req.end();
      

      HTTP 响应

      HTTP 代理

      为了重用 TCP 连接,http 模块包含一个默认的客户端代理对象 http.globalAgent。

      它对每个服务器端(host+port)创建的连接进行了管理,默认情况下,通过 http 提供的 ClientRequest 对象对同一个服务发起的 HTTP 请求最多可以创建5个连接。

      可以在 options 中传递 agent 选项,更改连接数限制。

      HTTP 客户端事件

      responsesocketconnectupgradecontinue

    四、构建 WebSocket 服务

    相比 HTTP,WebSocket 更接近于传输层协议,它并没有在 HTTP 的基础上模拟服务器端的推送,而是在 TCP 上定义独立的协议。

    WebSocket 协议主要分为两个部分:握手和数据传输。

    五、网络服务与安全


  • 相关阅读:
    61. Rotate List
    60. Permutation Sequence
    59. Spiral Matrix II
    57. Insert Interval
    18多校8th
    2019山东省赛总结
    二分图——poj2239
    二分图匹配——poj1469
    二分图——poj2446匈牙利算法
    思维构造,建图——cf1159E
  • 原文地址:https://www.cnblogs.com/Ruth92/p/6132803.html
Copyright © 2011-2022 走看看