1. 构建TCP服务器。
1.1 创建TCP服务器。
var net =require('net');
net.createServer(function(socket){
//创建新连接 每当有connection事件发生时,都会执行回调
socket.on('data', function(data){
//获取数据
});
socket.on('end', function(data){
//关闭连接
});
socket.write('some string'); //向客户端发送数据。
}).listen(4001);
说明:(1)启动这个例子,当服务器运行时可以应用telnet或者nc来链接它
Eg: telnet localhost 4001 (会在客户端看到some string)
(2) socket对象是可读流也是可写流。所以可以调用socket.pause()和socket.resume()来控制数据流。还有socket.pipe()
(3) 服务器对象也是一个发射器,所以也可在其生命周期内监听事件,.net Server发射以下事件:
- listening: 当服务器在指定的端口和地址监听时。
- connection: 当有新的链接创建时。回调函数会接收对应的套接字对象
- close: 当服务器被关闭时。
- error: 当在服务器层面发生错误时。
Eg:
var net = require('net');
var server = net.createServer();
var port = 4001;
server.on('listening', function(){
console.log("Server is listening on the port:",port);
});
server.on('connection', function(socket){
console.log("Server has a new connection");
socket.end(); //?
server.close(); //? 应该是为了让下面触发close事件
});
server.on('close', function(){
console.log("Server is now closed");
});
server.on('error', function(err){
console.log("Error occurred:", err.message);
});
server.listen(port);
说明:(1)连接后会在服务器控制台下看到上面输出的信息。
(2)当一段时间没有发出或者接收信息时,我们就可以设置自动关闭
(3) 通过设置socket.setKeepAlive(true,10000); 来保证两个终端的链接处于运行状态。
第二个可选参数规定发送空包延时时间。
1.2 构建一个简单的TCP聊天服务器。
var net= require('net');
varserver = net.createServer();
varsockets = []; //向所有客户端广播用户数据
server.on('connection',function(socket){
console.log("got a newconnection");
sockets.push(socket); //将连接存入某个位置
socket.on('data', function(data){
console.log("got data:",data);
sockets.forEach(function(otherSocket){
if(otherSocket !== socket){
otherSocket.write(data); //广播给其他用户
}
});
});
socket.on('close', function(){ //哪个用户关闭,就把它从地址池中删除。
console.log("connection isclosed");
var index = sockets.indexOf(socket);
sockets.splice(index, 1);
});
});
server.on('error',function(err){
console.log("Server error:",err.message);
});
server.on('close',function(){
console.log("Server is closed");
});
server.listen(4001);
说明:测试是启动服务器后,打开几个单独的客户端窗口(cmd)然后telnet到服务器。
2. 构建TCP客户端
2.1 连接服务器
var net =require('net');
var conn= net.createConnection(4000, host, function(){});
// 第一个参数连接端口 第二个参数连接主机 本地可以省略 可以连接www.fff.com 连接成功之后可执行回调
说明:(1)net.createConnection()返回值是net.Socket类的一个实例,它表示与服务器的连接,它既是可读流又 是可写流。
(2)可写流: conn.write("hello");
(3)可读流:conn.on('data',function(data){});
(4)终止连接:conn.end();
(5)处理错误:conn.on('error',function(){});
2.2 创建命令行TCP客户端示例
客户端运行代码:
var net = require('net');
var retryInterval = 3000;
var retriedTimes = 0;
var maxRetries = 10;
var quiting = false;
process.stdin.resume();
(function connect(){ //保证在连接终止时,重新连接。
function reconnect(){
if(retriedTimes >= maxRetries){
throw new Error('Max retries have been exceeded,i give up');
}
retriedTimes += 1;
setTimeout(connect, retryInterval);
}
var conn = net.createConnection(4000, function(){
console.log('Connect to server');
});
conn.on('error', function(err){
console.log(err.message);
});
conn.on('close', function(){
if(!quiting){
console.log("connect got closed,will try to reconnect");
reconnect();
}
});
//将服务器发送给进程的标准输出流打印出来
conn.pipe(process.stdout, {end:false});
//向服务器发送输入的数据
//process.stdin.pipe(conn);
process.stdin.on('data', function(data){
if(data.toString().trim().toLowerCase() === 'quit'){
quiting = true;
console.log('quiting....');
conn.end('bye bye'); //这里也可以使用conn???
process.stdin.pause();
}else{
conn.write(data); //向服务器发送数据
}
});
}());
服务器端运行代码:
var net = require('net');
net.createServer(function(socket){
console.log('have a connection');
socket.on('data', function(data){
console.log("got data from client:",data.toString());
if(data){
socket.write(data);
}
});
//socket.write("hello");
}).listen(4000);
说明:
(1) 当Node进程启动时,就准备好了process.stdin流来接受用户的键盘输入。这个可读流初始化时,处于暂停 状态,只有在恢复它之后,才会发射data事件,调用process.stdin.resume()来恢复。
(2)数据通过conn可写流传入到服务器。.pipe()第一个参数是:目标可写流。
Process.stdin.pipe(conn);
(3) 将服务器发送给进程标准输出流打印出来。为了防止进程的标准输出流会在连接关闭之后关闭.pipe()引入第二 个可选参数:end选项
conn.pipe(process.stdout, {end:false});