网络编程:构建 TCP 服务

 

1. 创建简易TCP服务端

var net = require('net');
var server = net.createServer();

server.on('connection', function(socket){
	socket.write("欢迎光临《深入浅出Node.js》示例:\n");
});

server.on('end', function () {
	console.log('连接断开');
});

server.listen(8124, function () {
	console.log('server bound');
});

2.创建与客户端交互的TCP服务端: server.js

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

3. 创建客户端: client.js

var net = require('net');
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("from server:", data.toString());
	client.end();
});
client.on('end', function () {
	console.log('client disconnected');
});

4. 执行结果

首先启动服务器端,然后启动客户端,结果如下

xiao@uXiao:~/nodejs/深入浅出nodejs/chapter7$ node server.js 
server bound
from client: world!

连接断开
xiao@uXiao:~/nodejs/深入浅出nodejs/chapter7$ node client.js 
client connected
from server: 欢迎光临《深入浅出Node.js》示例:

from server: 你好
client disconnected

5. TCP服务的事件

在上述的示例中,代码分为服务器事件和连接事件

5.1. 服务器事件

对于通过 net.createServer() 创建的服务器而言,它是一个 EventEmitter 实例,它的自定义事件有如下几种。

  • listening :在调用 server.listen() 绑定端口或者Domain Socket后触发,简洁写法为server.listen(port,listeningListener) ,通过 listen() 方法的第二个参数传入。
  • connection :每个客户端套接字连接到服务器端时触发,简洁写法为通过 net.create-Server() ,最后一个参数传递。
  • close :当服务器关闭时触发,在调用 server.close() 后,服务器将停止接受新的套接字连接,但保持当前存在的连接,等待所有连接都断开后,会触发该事件。
  • error :当服务器发生异常时,将会触发该事件。比如侦听一个使用中的端口,将会触发一个异常,如果不侦听 error 事件,服务器将会抛出异常。

5.2. 连接事件

服务器可以同时与多个客户端保持连接,对于每个连接而言是典型的可写可读 Stream 对象。Stream 对象可以用于服务器端和客户端之间的通信,既可以通过 data 事件从一端读取另一端发来的数据,也可以通过 write() 方法从一端向另一端发送数据。它具有如下自定义事件。

  • data :当一端调用 write() 发送数据时,另一端会触发 data 事件,事件传递的数据即是write() 发送的数据。
  • end :当连接中的任意一端发送了 FIN 数据时,将会触发该事件。
  • connect :该事件用于客户端,当套接字与服务器端连接成功时会被触发。
  • drain :当任意一端调用 write() 发送数据时,当前这端会触发该事件。
  • error :当异常发生时,触发该事件。
  • close :当套接字完全关闭时,触发该事件。
  • timeout :当一定时间后连接不再活跃时,该事件将会被触发,通知用户当前该连接已经被闲置了。

6. Nagle算法

TCP针对网络中的小数据包有一定的优化策略:Nagle算法。如果每次只发送一个字节的内容而不优化,网络中将充满只有极少数有效数据的数据包,将十分浪费网络资源。Nagle算法针对这种情况,要求缓冲区的数据达到一定数量或者一定时间后才将其发出,所以小数据包将会被Nagle算法合并,以此来优化网络。这种优化虽然使网络带宽被有效地使用,但是数据有可能被延迟发送。

在Node中,由于TCP默认启用了Nagle算法,可以调用 socket.setNoDelay(true) 去掉Nagle算法,使得 write() 可以立即发送数据到网络中。

另一个需要注意的是,尽管在网络的一端调用 write() 会触发另一端的 data 事件,但是并不意味着每次 write() 都会触发一次 data 事件,在关闭掉Nagle算法后,另一端可能会将接收到的多个小数据包合并,然后只触发一次 data 事件。

你可能感兴趣的:(深入浅出nodejs)