Nodejs创建TCP服务器 - king0222
1.Nodejs提供了net模块给我们,所以我们创建TCP服务器很简单:
require('net').createServer(function(socket){
//newconnection
socket.on('data',function(data){
//gotdata
});
socket.on('end',function(data){
//connectionclosed
});
socket.write('Somestring');
}).listen();
通过varserver=require('net').createServer();这行代码我们可以得到tcp服务器对象的引用。
server对象具注册了以下几个监听事件:
listening,connection,close,error
下面一个例子是在TCP服务器的声明周期中监听了如上几个事件:
varserver=require('net').createServer();
varport=;
server.on('listening',function(){
console.log('Serverislisteningonport',port);
});
server.on('connection',function(socket){
console.log('Serverhasanewconnection');
socket.end();
server.close();
});
server.on('close',function(){
console.log('Serverisnowclosed');
});
server.on('error',function(err){
console.log('Erroroccurred:',err.message);
});
server.listen(port);
一旦建立连接成功后,会得到一个socket对象作为回调中的参数,我们可以操作这个socket对象,前面提到过tcp连接的对象是可读可写的流。作为一个流对象,因此能够监听data,end等事件;作为一个可写流,具有write()方法。下面是一个能够监听用户输入的例子:
varserver=require('net').createServer(function(socket){
console.log('newconnection');
socket.setEncoding('utf');
socket.write("Hello!Youcanstarttyping.Type'quit'toexit.\n");
socket.on('data',function(data){
console.log('got:',data.toString())
if(data.trim().toLowerCase()==='quit'){
socket.write('Byebye!');
returnsocket.end();
}
//反馈回客户端
socket.write(data);
});
socket.on('end',function(){
console.log('Clientconnectionended');
});
}).listen();
因为socket对象又是一个可读的流,因此你能够空气他的pause()和resume(),或者你可以直接使用pipe()方法输出一个可写流:
varws=require('fs').createWriteStream('helloworld.txt');
require('net').createServer(function(socket){
socket.pipe(ws);
}).listen();
上面的代码创建了一个可写流对象,然后将这个可写流对象输出到客户端。在客户端可以得到一个名为helloworld.txt的文件,
可以用“telnetlocalhost4001”来测试该例子。
因为socket对象同时具有可读流的性质和可写流的性质,因此上面的例子你可以反过来形成下面这样的代码:
require('net').createServer(function(socket){
varrs=require('fs').createReadStream('hello.txt');
rs.pipe(socket);
}).listen();
上面的代码将hello.text文件内容输出到socket对象中返回给客户端,当内容输出完成后,tcp连接就会退出,在前面的文章中有说过Pipe的用法,默认情况下在数据读取完成后就会执行end方法,因此如果不想要这样的效果并保持连接的话可以在pipe中添加第二个参数:{end:false},并重写end监听。
2.闲置socket当有闲置的socket出现的时候我们需要进行相应的清除的工作,由setTimeout方法可以帮我们把闲置的socket对象关闭。
vartimeout=;//minute
socket.setTimeout(timeout);
socket.on('timeout',function(){
socket.write('idletimeout,disconnecting,bye!');
socket.end();
});
下面是一个更简洁的使用方式:
socket.setTimeout(60000,function(){
socket.end('idletimeout,disconnecting,bye!');
});
3.保持连接
socket.setKeepAlive(true);
你也可以添加第二个参数在设置可延时时长:
socket.setKeepAlive(true,10000);//10seconds
4.是否使用延时
kernel会在发送tcp数据包之前缓存数据,因此会占据一定的延时,这对于某些小数据包场景来说是有用的,但如果你不希望有这样的延时的话,那么你可以这样设置:
socket.setNoDelay(true); varport=; varhost='...'; server.listen(port,host);
listen方法的第二个参数是监听客户端的ip地址,如果填写则只监听所填写的ip,否则则监听所有ip地址,默认情况下不填写。关闭服务器连接,我们可以使用close方法,同时也可以对该事件进行监听。
server.close();
server.on('close',function(){
console.log('serverclosed!');
});
6.创建一个简单的TCP聊天室服务器
varnet=require('net');
varserver=net.createServer();
varsockets=[];
server.on('connection',function(socket){
console.log('gotanewconnection');
sockets.push(socket);
console.log('socketslength:',sockets.length);
socket.on('data',function(data){
console.log('gotdata:',data.toString());
sockets.forEach(function(otherSocket){
if(otherSocket!==socket){
otherSocket.write(data);
}
});
});
socket.on('close',function(){
console.log('connectionclosed');
varindex=sockets.indexOf(socket);
sockets.splice(index,);
console.log('socketslength:',sockets.length);
});
});
server.on('error',function(err){
console.log('Servererror:',err.message);
});
server.on('close',function(){
console.log('Serverclosed');
});
server.listen();