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

第7章 网络编程

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

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

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

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》示例:\n');
    }); 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!\r\n');
    }); 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)服务器事件: listening、 connection、 close 、 error

    (2)连接事件: data、 end、 connect、 drain、 error、 close、 timeout

    注意,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 套接字事件

    message、listening、close、error

三、构建 HTTP 服务

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

var http = require('http');

http.createServer(function(req, res) {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end('Hello World\n');
}).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 模块

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

    ① HTTP 请求:

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

    ② HTTP 响应:

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

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

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

    ③ HTTP 服务的事件

    connection、request、close、checkContinue、connect、upgrade、clientError

  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 客户端事件

    response、socket、connect、upgrade、continue

四、构建 WebSocket 服务

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

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

五、网络服务与安全

《深入浅出Node.js》第7章 网络编程的更多相关文章

  1. 《深入浅出Node.js》第6章 理解 Buffer

    @by Ruth92(转载请注明出处) 第6章 理解 Buffer ✁ 为什么需要 Buffer? 在 Node 中,应用需要处理网络协议.操作数据库.处理图片.接收上传文件等,在网络流和文件的操作中 ...

  2. 深入浅出Node.js(一):什么是Node.js

    Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node.jsS创始人Ryan Dalh加盟Joyent获得企业资助,再到 ...

  3. 一个月时间整理《深入浅出Node.js》

    今天终于把朴灵老师写的<深入浅出Node.js>给学习完了, 这本书不是一本简单的Node入门书籍,它没有停留在Node介绍或者框架.库的使用层面上,而是从不同的视角来揭示Node自己内在 ...

  4. 深入浅出Node.js(一):什么是Node.js(转贴)

    以下内容转自:http://www.infoq.com/cn/articles/what-is-nodejs/ 作者:崔康 [编者按]:Node.js从2009年诞生至今,已经发展了两年有余,其成长的 ...

  5. 《深入浅出node.js(朴灵)》【PDF】下载

    <深入浅出node.js(朴灵)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062563 内容简介 <深入浅出Node. ...

  6. 深入浅出Node.js(上)

    (一):什么是Node.js Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node.jsS创始人Ryan Dalh加盟 ...

  7. 读书笔记: 深入浅出node.js

    >> 深入浅出node.js node.js是c++编写的js运行环境 浏览器: 渲染引擎 + js引擎 后端的js运行环境 node.js用google v8引擎,同时提供很多系统级的A ...

  8. 深入浅出node.js游戏服务器开发1——基础架构与框架介绍

    2013年04月19日 14:09:37 MJiao 阅读数:4614   深入浅出node.js游戏服务器开发1——基础架构与框架介绍   游戏服务器概述 没开发过游戏的人会觉得游戏服务器是很神秘的 ...

  9. 《深入浅出Node.js》学习笔记(一)

    看了朴灵前辈的node.js系列文章,很开阔视野,虽然能力有限还是有很多不懂,但是还是希望能写下笔记,初步对node.js有点了解. 一.概念 Node.js不是JS应用.而是JS运行平台 Node. ...

随机推荐

  1. 高性能Web服务器Nginx的配置与部署研究系列(1)-- 入门 hello work

    简介: Nginx 是一个基于 BSD-like 协议.开源.高性能.轻量级的HTTP服务器.反向代理服务器以及电子邮件(SMTP.POP3.IMAP)服务器.Nginx 是由一个俄罗斯的名叫“Igo ...

  2. [转载]GlassFish 的安装及设置命令

    移步: http://blog.csdn.net/joyous/article/details/8008870

  3. 【图像处理】【SEED-VPM】1.板子基本操作流程

    >>>>>>>>>>>>>>>>>>>>>>>>> ...

  4. python split()函数

    Python split()函数 函数原型: split([char][, num])默认用空格分割,参数char为分割字符,num为分割次数,即分割成(num+1)个字符串 1.按某一个字符分割. ...

  5. 适配iOS10 的相关权限设置

    解决办法(fix method):在info.plist —Source Code中添加UsageDescription相关的key, 描述字符串自己随意填写就可以,但是一定要填写,不然会引发包无效的 ...

  6. 如何在HTML5 Canvas 里面显示 Font Awesome 图标

        Font Awesome 是一套完美的图标字体,主要目的是和 Bootstrap 搭配使用. 提供的CSS 已经可以完美显示这些图标在网页里面.最新的版本4.3 里面,已经提供519 Icon ...

  7. mysql连接查询和子查询

    一.连接查询 1.交叉连接 就是从一张表的一条记录去连接另一张表中的所有记录,并且保存所有的记录,其中包括两个表的所有的字段! 从结果上看,就是对两张表做笛卡尔积! 笛卡尔积也就是两个表中所有可能的连 ...

  8. js回顾2

    1:事件流:一个事件发生时按一个方向传播 eg:a标签->html 冒泡:从里到外(一般的选择)-----IE只有冒泡 捕获:从外到里-----网景只有捕获(已经不存在了) 2.事件处理的两种种 ...

  9. is a 、like a、has a

    has a 代表的是对象和它的成员的从属关系.可以分为组合与聚合两种. 组合:表示两个对象是整体与部分的关系为强关系 聚合:表示两个对象是整体与部分的关系为弱关系 is a 它是类继承关系,只是覆盖了 ...

  10. linux环境下安装jdk

    1.查看系统自带的jdk #RPM -qa|grep jdk 若存在则删除 jdk-1.7.0_67-fcs.x86_64 #rpm -e --nodeps jdk-1.7.0_67-fcs.x86_ ...