Node提供了net dgram http https4个模块,分别用于处理TCP、UDP、HTTP、HTTPS,适用于服务器端和客户端。
应用层 HTTP、SMTP、IMAP
表示层 加密/解密等
会话层 通信连接/维持会话等
传输层 TCP/UDP
网络层 IP
链路层 网络特有的链路接口
物理层 网络物理硬件
TCP三次握手
客户端发送请求连接,服务器端响应,客户端开始传输
1 创建TCP服务器端
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("欢迎光临\n");
});
server.listen(8124,function(){
console.log('server bound');
})
var server = net.createServer(function(socket){
socket.on('data',function(data){
socket.write('你好');
});
socket.on('end',function(){
console.log('连接断开');
});
socket.write("欢迎光临\n");
});
server.listen(8124,function(){
console.log('server bound');
})
我们通过net.createServer(listener)即可建立一个TCP服务器,listener是连接事件connection的侦听器。
TCP服务的事件
服务器事件:
listening
connection
close
error
连接事件:
data
end
connect
drain
error
close
timeout
由于TCP套接字是可读可写的stream对象,可以利用pipe()方法巧妙地实现管道操作,如下:
var net = require('net');
var server = net.createServer(function(socket){
socket.write('Echo server\r\n');
socket.pipe(socket);
});
server.listen(1337,'127.0.0.1');
2 构建UDP服务
UDP与TCP最大的不同是UDP不是面向连接的,
TCP中连接一旦建立,所有的会话都基于连接完成,客户端如果要与另一个TCP服务通信,需要另建立一个套接字来完成连接。但在UDP中,一个套接字可以与多个UDP服务通信,它虽然提供面向事务的简单不可靠信息传输服务,在网络差的情况下存在丢包严重的问题,但是由于它无须连接,资源消耗低,处理快速且灵活,所以常常应用在那种偶尔丢一两个数据包也不好产生重大影响的场景,比如音频、视频等。DNS服务就是基于UDP实现的。
创建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);
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套接字相对TCP套接字使用起来更简单,它只是一个EventEmitter的实例,而非Stream的实例。有如下事件
message:当UDP套接字侦听网卡端口后,接收到消息时触发该事件,触发携带的数据为消息buffer对象和一个远程地址信息。
listening: 当UDP套接字开始侦听时触发该事件
close: 调用close时触发该事件,并不再触发message事件
error: 当异常发生时触发该事件,如果不侦听,异常将直接抛出,使进程退出。
3 构建HTTP服务器
HTTP 超文本传输协议,在http的两端是服务器和浏览器,即著名的B/S模式。
网络通信的报文分为四个部分:
一是TCP的三次握手
二是在完成握手之后,客户端向服务器端发送请求报文
三是服务器端完成处理后,向客户端发送响应内容,包括响应头和响应体
最后是结束会话的意思
Http的特点:它是基于请求响应式的,以一问一答的方式实现服务,虽然基于TCP会话,但是本身并无会话的特点。
http只做两件事:处理http请求和发送http响应
以浏览器打开一张图片地址为例:首先,浏览器构造http报文发向图片服务器端;然后,服务器端判断报文中的要请求的地址,将磁盘中的图片文件以报文的形式发送给浏览器;浏览器接收完图片后,调用渲染引擎将其显示给用户。
3.1http请求
3.2http响应
影响响应头报文头部信息的API为res.setHeader()和res.writeHead()
我们可调用setHeader进行多次设置,但只有调用writeHead后,报文才会写入到连接中
3.3HTTP服务的事件
服务器也是一个EventEmitter实例
connection事件
request事件
close事件
checkContinue事件
connect事件
upgrade事件 : ws协议升级
clientError事件
未完待续
4 构建webSocket服务
与node完美契合
1websocket客户端基于事件的编程模型与node中自定义事件相差无几
2websocket实现了客户端与服务器端之间的长连接,而node事件驱动的方式十分擅长与大量的客户端保持高并发连接。
与http相比,webSocket的优点
1客户端与服务器只建立一个TCP连接,可以使用更少的连接
2websocket服务器端可以推送数据到客户端,这远比HTTP请求响应模式更灵活、高效
3有更轻量级的协议头,减少数据传输量。
var socket = new WebSocket('ws://127.0.0.1:12010/updates');
socket.open = function(){
setInterval(function(){
if(socket.bufferedAmount == 0)
socket.send(getUpdateData());
},50);
};
socket.onmessage = function(event){
//TODO:event.data
}
在ws之前,网页客户端与服务端进行通信最高效的是Comet技术。实现Comet技术的细节是采用长轮询或iframe流。
长轮询的原理:客户端向服务端发起请求,服务器端只在超时或有数据响应式断开连接(res.end());客户端在收到数据或者超时后重新发起请求。