网络编程
构建tcp服务
TCP
tcp全名为传输控制协议。再osi模型中属于传输层协议。
tcp是面向连接的协议,在传输之前需要形成三次握手形成会话
只有会话形成了,服务端和客户端才能想发送数据,在创建会话的过程中,服务端和客户端分别提供一个套接字。两个套接字共同形成一个连接, 服务端和客服端通过套接字实现两者的操作
创建TCP服务端
var net = require('net')
var server = net.createServer(function (socket) {
// 新的连接
socket.on('data',function(data) {
socket.write('你好')
})
socket.on('end', function(data) {
console.log('连接断开')
})
socket.write('welcome to the new world')
})
// 监听方式
server.listen(8124, function() {
console.log('server bound')
})
// 新的连接
server.on('connection', function(socket) {
})
TCP服务的事件
服务器事件
对于net.createServer()创建的服务器而言,是一个eventEmitter
实例,自定义的事件有如下几种
- listening: server.listen()绑定端口。
- connection: 每个客户端套接字连接到服务器端的时候触发。
- close: 当服务器关系触发的时候,在调用server.close()
- error: 当服务器发生异常的时候, 会触发该事件。
连接事件
服务端可以同多个客户端保持连接。对于每个连接而言都是典型的可读可写的stream对象。stream对象
可以用于服务端和客户端之间的通信,既可以是通过data事件从一段到另一端发来的数据,也可以通过write方法从一段向另一端发送数据。
- data: 当一端通过write发送数据,另一端会触发data事件
- end: 当连接中的任意一端发送了FIN数据,当套接字和服务端成功会被触发
- connect: 该事件用于客户端,当套接字和服务端连接成功的时候会触发
- error: 当异常发生的时候,触发该事件
- close: 当套接字完全关闭的时候,触发该事件
- timeout: 当一定时间后连接不在活跃的时候,该事件会被触发。通知用户已经被闲置了
- drain: 当任意一段调用write发送数据时, 当前这端会触发该事件
tcp套接字是可写可读的stream对象,可以利用pipe方法巧妙的实现管道操作
var net = require('net')
var server = net.createServer(function(socket){
socket.write('Echo server')
socket.pipe(socket)
})
server.listen(1337, '127.0.0.1')
TCP针对网络中的小数据包有一定的优化策略:Nagle算法。如果每次只发送一个字节的内容而不优化,网络中将充满只有极少数有效数据的数据包,将十分浪费网络资源。Nagle算法针对这种情况,要求缓冲区的数据达到一定数量或者一定时间后才将其发出,所以小数据包将会被Nagle算法合并,以此来优化网络。
构建UDP服务
UDP不是面向连接的。一个套接字可以与多个UDP服务通信,它虽然提供面向事务的简单不可靠信息传输服务,在网络差的情况下存在丢包严重的问题
创建UDP套接字
UDP套接字一旦创建,既可以作为客户端发送数据,也可以作为服务器端接收数据。
var dgram = require('dgram')
var socket = dgram.createSocket("udp4")
创建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('深入nodejs')
var client = dgram.createSocket("udp4")
client.send(message, 0, message.length, 41234, "localhost", function(err, bytes) {
client.close()
})
api: socket.send(buf, offset, length, port, address, [callback])
upd套接字事件
- message: 收到信息的时候触发该事件,携带数据为消息buffer和一个远程地址信息
- listening: upd套接字来来时监听该事件
- close: 调用close可以触发该事件。不在触发message事件。
- error: 发生异常的时候触发该事件,不监听,异常之间抛出。