利用Node能够十分方便的搭建网络服务器。算法
Node提供了net、dgram、http、https等4个模块,分别用于处理TCP、UDP、HTTP、HTTPS,适用于服务器端和客户端。编程
TCP服务在网络应用中十分常见,大多数的应用都是基于TCP搭建而成的。浏览器
TCP全名为传输控制协议,在OSI模型(物理层、数据链路层、网络层、传输层、会话层、表示层、应用层)中属于传输层协议。安全
TCP是面向链接的协议,其显著的特征是传输以前须要3次握手造成会话。bash
只有会话造成后,服务器端和客户端之间才能相互发送数据。在建立会话的过程当中,服务器端和客户端分别提供一个套接字,这两个套接字共同造成一个链接。服务器端和客户端则经过套接字实现二者之间的操做。服务器
经过net.createServer(listener)便可建立一个TCP服务器,listener是链接事件connection的侦听器。网络
能够利用Telnet工具做为客户端对建立的服务器进行会话交流。并发
TCP服务的事件分为服务器事件和链接事件。socket
服务器事件高并发
对于经过net.createServer()建立的服务器而言,它是一个EventEmitter实例,自定义事件有:
链接事件
服务器能够同时与多个客户端保持链接,对于每一个链接而言是典型的可写可读Stream对象。Stream对象能够用于服务器端和客户端之间的通讯,既能够经过data事件从一端读取另外一端发来的数据,也能够经过write()方法从一端向另外一端发送数据。自定义事件:
TCP套接字是可写可读的Stream对象,能够利用pipe()方法巧妙地实现管道操做。
TCP针对网络中的小数据也有必定的优化策略:Nagle算法。
Nagle算法:
要求缓冲区的数据达到必定数量或者必定时间后才将其发出,因此小数据包会被Nagle算法合并,所以来优化网络。虽然网络带宽被有效地使用,可是数据有可能被延迟发送。
UDP全称为用户数据包协议,与TCP同样属于网络传输层。UDP和TCP最大的不一样是UDP不是面向链接的。
建立UDP套接字十分的简单,UDP套接字一旦被建立,既能够做为客户端发送数据,也能够做为服务器端接收数据。
var dgram = rerquire('dgram');
var socket = dgram.createSocket("udp4");
复制代码
想要UDP套接字接收网络信息,只要调用dgram.bind(port,[address])方法对网卡和端口进行绑定便可。
建立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);
});
server.bind(41234);
复制代码
建立UDP客户端示例:
var dgram = require('dgram');
var message = new Buffer("深刻浅出Node.js");
var client = dgram.createSocket("udp4");
client.send(message, 0, message.length, 41234, "localhost", function (err, bytes) {
client.close();
});
复制代码
UDP套接字只是一个EventEmitter的实例。自定义事件:
Node提供了基本的http和https模块用于HTTP和HTTPS的封装。
HTTP服务器的实现:
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/');
复制代码
初始HTTP
HTTP的全称是超文本传输协议(HyperText Transfer Protocol)。
HTTP构建在TCP之上,属于应用层协议。
HTTP报文
HTTP是基于请求响应式的,以一问一答的方式实现服务。
HTTP服务只作两件事:处理HTTP请求和发送HTTP响应。
不管是HTTP请求报文仍是HTTP响应报文,报文内容都包含两个部分:报文头和报文体。
Node的http模块包含对HTTP处理的封装。
在Node中,HTPP服务继承自TCP服务器(net模块),它可以与多个客户端保持链接,因为其采用事件驱动的形式,并非为每个链接建立额外的线程或进程,保持很低的内存占用,因此可以实现高并发。
HTTP服务和TCP服务模型的区别在于,在开启keepalive后,一个TCP会话能够用于屡次请求和响应。TCP服务以connection为单元进行服务,HTTP服务以request为单位进行服务。
http模块将链接所用套接字的读写抽象为ServerRequest和ServerResponse对象,分别对应请求和响应操做。
HTTP请求
对于TCP链接的读操做,http模块将其封装为ServerRequest对象。
HTTP响应
HTTP响应对象封装了对底层链接的写操做,能够将其看作一个可写的流对象。
响应结束后,HTTP服务器可能会将当前的链接用于下一个请求,或者关闭链接。
HTTP服务的事件
HTTP服务也是个EventEmitter实例:
HTTP客户端是服务器服务模型的另外一部分,处在HTTP的另外一端,在整个报文的参与中,报文头和报文体由它产生。
HTTP响应
HTTP客户端在CLientRequest对象中,它的事件叫作response。
HTTP代理
http提供的ClientRequest对象是基于TCP层实现的,在keepalive的状况下,一个底层会话链接能够屡次用于请求。为了重用TCP链接,http模块包含一个默认的客户端代理对象http。globalAgent.t它对每一个服务器端(host+port)建立的链接进行了管理,默认状况下,经过ClientRequest对象对同一个服务器发起的HTTP请求最多能够建立5个链接。它的实质是一个链接池。
调用HTTP客户端同时对一个服务器发起10次请求时,其实质只有5个请求处于并发状态,后续的请求完成服务后才真正发出。这与浏览器对同一个域名有下载链接数的限制是相同的行为。
HTTP客户端事件
WebSocket与Node之间的配合堪称完美的理由:
WebSocket与传统HTTP的好处:
使用WebSocket,网页客户端只须要一个TCP链接便可完成双向通讯,在服务器与客户端频繁通讯时,无须频繁断开链接和重发请求。
WebSocket与HTTP的区别:
相比HTTP,WebSocket更接近于传输层协议,并无在HTTP的基础上模拟服务器端的推送,而是在TCP上定义的独立的协议。
WebSocket协议主要分为两个部分:握手和数据传输。
一旦WebSocket握手成功,服务器端与客户端将会呈现对等的效果,都能接收和发送消息。
在握手顺利完成后,当前链接再也不进行HTTP的交互,而是开始WebSocket的数据帧协议。实现客户端与服务器端的数据交换。
密钥
TLS/SSL是一个公钥/私钥的结构,它是一个非对称的结构,每一个服务器端和客户端都有本身的公私钥。
公钥用来加密要传输的数据,私钥用来解密接收到的数据。
公钥和私钥是配对的,经过公钥加密的数据,只有经过私钥才能解密,因此在创建安全传输以前,客户端和服务器端之间须要互换公钥。客户端发送数据时要经过服务器端的公钥进行加密,服务器端发送数据时则须要客户端的公钥进行加密。
公私钥的非对称加密虽好,可是网络中依然可能存在窃听的状况,典型的例子就是中间人攻击。
客户端和服务器端在交换公钥的过程当中,中间人对客户端扮演服务器端的角色,对服务器端扮演客户端的角色,所以客户端和服务器端几乎感觉不到中间人的攻击。
为了解决中间人攻击,数据传输过程当中还须要对获得的公钥进行认证,以确认获得的公钥是出自目标服务器。
数字证书
为了确保数据的安全,引入第三方:CA(Certificate Authority,数字证书认证中心)。
CA的做用是为站点颁发证书,且这个证书中具备CA经过本身的公钥和私钥实现的签名。
为了获得签名证书,服务器端须要经过本身的私钥生成CSR(Certificate Signing Request,证书签名请求)文件。CA机构将经过这个文件颁发属于该服务器的签名证书,只要经过CA机构就能验证证书是否合法。
与普通的TCP服务器端和客户端相比,TLS的服务器端和客户端仅仅只在证书的配置上有差异,其他部分基本相同。
HTTPS服务就是工做在TLS/SSL上的HTTP。