zoukankan      html  css  js  c++  java
  • Nodejs创建TCP服务器

    Nodejs创建TCP服务器

    1.Nodejs提供了net模块给我们,所以我们创建TCP服务器很简单:

     1 require('net').createServer(function(socket) {
     2     // new connection
     3     socket.on('data', function(data) {
     4         // got data
     5     });
     6     socket.on('end', function(data) {
     7         // connection closed
     8     });
     9     socket.write('Some string');
    10 }).listen(4001);

    通过var server = require('net').createServer();这行代码我们可以得到tcp服务器对象的引用。
    server对象具注册了以下几个监听事件:
    listening,connection,close,error
    下面一个例子是在TCP服务器的声明周期中监听了如上几个事件:

     1 var server = require('net').createServer();
     2 var port = 4001;
     3 server.on('listening', function() {
     4     console.log('Server is listening on port', port);
     5 });
     6 server.on('connection', function(socket) {
     7     console.log('Server has a new connection');
     8     socket.end();
     9     server.close();
    10 });
    11 server.on('close', function() {
    12     console.log('Server is now closed');
    13 });
    14 server.on('error', function(err) {
    15     console.log('Error occurred:', err.message);
    16 });
    17 server.listen(port);

    一旦建立连接成功后,会得到一个socket对象作为回调中的参数,我们可以操作这个socket对象,前面提到过tcp连接的对象是可读可写的流。作为一个流对象,因此能够监听data,end等事件;作为一个可写流,具有write()方法。
    下面是一个能够监听用户输入的例子:

     1 var server = require('net').createServer(function(socket) {
     2     console.log('new connection');
     3     socket.setEncoding('utf8');
     4     socket.write("Hello! You can start typing. Type 'quit' to exit.
    ");
     5     socket.on('data', function(data) {
     6         console.log('got:', data.toString())
     7         if (data.trim().toLowerCase() === 'quit') {
     8             socket.write('Bye bye!');
     9             return socket.end();
    10         }
    11         //反馈回客户端
    12         socket.write(data);
    13     });
    14     socket.on('end', function() {
    15         console.log('Client connection ended');
    16     });
    17 }).listen(4001);

    因为socket对象又是一个可读的流,因此你能够空气他的pause()和resume(),或者你可以直接使用pipe()方法输出一个可写流:

    1 var ws = require('fs').createWriteStream('helloworld.txt');
    2 require('net').createServer(function(socket) {
    3     socket.pipe(ws);
    4 }).listen(4001);

    上面的代码创建了一个可写流对象,然后将这个可写流对象输出到客户端。在客户端可以得到一个名为helloworld.txt的文件,
    可以用“telnet localhost 4001”来测试该例子。
    因为socket对象同时具有可读流的性质和可写流的性质,因此上面的例子你可以反过来形成下面这样的代码:

    1 require('net').createServer(function(socket) {
    2     var rs = require('fs').createReadStream('hello.txt');
    3     rs.pipe(socket);
    4 }).listen(4001);

    上面的代码将hello.text文件内容输出到socket对象中返回给客户端,当内容输出完成后,tcp连接就会退出,在前面的文章中有说过Pipe的用法,默认情况下在数据读取完成后就会执行end方法,因此如果不想要这样的效果并保持连接的话可以在pipe中添加第二个参数:{ end : false },并重写end监听。

    2.闲置socket
    当有闲置的socket出现的时候我们需要进行相应的清除的工作,由setTimeout方法可以帮我们把闲置的socket对象关闭。

    1 var timeout = 60000; // 1 minute
    2 socket.setTimeout(timeout);
    3 socket.on('timeout', function() {
    4     socket.write('idle timeout, disconnecting, bye!');
    5     socket.end();
    6 });

    下面是一个更简洁的使用方式:

    1 socket.setTimeout(60000, function() {
    2     socket.end('idle timeout, disconnecting, bye!');
    3 });

    3.保持连接
    socket.setKeepAlive(true);
    你也可以添加第二个参数在设置可延时时长:
    socket.setKeepAlive(true, 10000); // 10 seconds


    4.是否使用延时
    kernel会在发送tcp数据包之前缓存数据,因此会占据一定的延时,这对于某些小数据包场景来说是有用的,但如果你不希望有这样的延时的话,那么你可以这样设置:
    socket.setNoDelay(true);


    5.监听关闭连接

    1 var port = 4001;
    2 var host = '0.0.0.0';
    3 server.listen(port, host);

    listen方法的第二个参数是监听客户端的ip地址,如果填写则只监听所填写的ip,否则则监听所有ip地址,默认情况下不填写。
    关闭服务器连接,我们可以使用close方法,同时也可以对该事件进行监听。

    1 server.close();
    2 server.on('close', function() {
    3     console.log('server closed!');
    4 });

    6.创建一个简单的TCP聊天室服务器

     1 var net = require('net');
     2 var server = net.createServer();
     3 var sockets = [];
     4 server.on('connection', function(socket) {
     5     console.log('got a new connection');
     6     sockets.push(socket);
     7     console.log('sockets length:', sockets.length);
     8     socket.on('data', function(data) {
     9         console.log('got data:', data.toString());
    10         sockets.forEach(function(otherSocket) {
    11             if (otherSocket !== socket) {
    12                 otherSocket.write(data);
    13             }
    14         });
    15     });
    16     socket.on('close', function() {
    17         console.log('connection closed');
    18         var index = sockets.indexOf(socket);
    19         sockets.splice(index, 1);
    20         console.log('sockets length:', sockets.length);
    21     });
    22 });
    23 server.on('error', function(err) {
    24     console.log('Server error:', err.message);
    25 });
    26 server.on('close', function() {
    27     console.log('Server closed');
    28 });
    29 server.listen(4001);

     7.常用插件

    7.1开发中可以安装supervisor来提高调试效率,这个插件可以保证我们每次修改完代码后都无需重新手动启动nodejs服务器,由supervisor帮我们自动搞定。

    npm install -g supervisor

    安装完成后可以: supervisor bin/www

    7.2在服务器环境中部署nodejs,我们不希望程序会断掉,因此,就需要一个能自动重启的服务来帮我们实现这一功能。

    $ sudo npm install forever -g   #安装
    $ forever start app.js          #启动
    $ forever stop app.js           #关闭
    $ forever start -l forever.log -o out.log -e err.log app.js   #输出日志和错误
  • 相关阅读:
    textarea中的空格与换行
    js判断微信内置浏览器
    关于express4不再支持body-parser
    html5 geolocation API
    屏幕密度与分辨率
    nodebeginer
    手机浏览器下IScroll中click事件
    iphone手机上的click和touch
    AngularJS学习笔记一
    不用bootstrap实现居中适应
  • 原文地址:https://www.cnblogs.com/moyiqing/p/node_tcp.html
Copyright © 2011-2022 走看看