Nodejs之套接字

Node.js的net模块提供了socket编程接口,方便我们利用较为底层的套接字接口来实现应用协议。这次我们看一个简单的回显服务器示例,包括服务端和客户端的代码。

使用JavaScript也可以进行套接字编程,哈哈,这酸爽!

代码

分服务器和客户端两部分来说吧。

服务器端:

var net = require("net");

// server is an instance of net.Server
// sock is an instance of net.Socket
var server = net.createServer(function(sock){
  console.log('client connected, address -  ', sock.remoteAddress, ' port - ', sock.remotePort);
  sock.setEncoding('utf8');
  sock.on('data', function(data){
    console.log('got data from client - ', data);
    sock.write(data);
  });

  sock.on('end', function(){
    console.log('client disconnected');
  });

  sock.on('error', function(err){
    console.log('socket error - ', err);
  });
});

server.maxConnections = 10;
server.listen(7, function(){
  console.log('echo server bound at port - 7');
});

net模块api在这里:https://nodejs.org/api/net.html

我使用net.createServer来创建一个服务器实例,这个方法的返回值是一个net.Server实例,net.Server提供了listen方法,让我们监听到某个端口上来接受客户端连接,同时还提供了一些属性,比如maxConnections可以设置服务器的并发连接数上限(当服务器的连接数超过这个值时,后续连接就会被拒掉),还有其它的,看文档吧:https://nodejs.org/api/net.html#net_class_net_server

net.Server还提供了一些事件,比如error、connection等。当有客户端连接被接受时,会发射connection事件,这个事件带一个net.Socket对象作为参数,可以在回调函数里访问这个net.Socket实例来与客户端交互。我在代码里,给createServer方法传入了一个callback来处理connection事件,实际上也可以略作修改,通过监听connection事件的方法处理客户端连接。新代码如下:

 

/**
 * Created by iwen on 16/11/5.
 */
var net = require("net");

var server = net.createServer();

server.on('connection', function (sock) {
    console.log('client connected, address -  ', sock.remoteAddress, ' port - ', sock.remotePort);
    sock.setEncoding('utf8');
    sock.on('data', function (data) {
        console.log('got data from client - ', data);
        sock.write(data);
    });

    sock.on('end', function () {
        console.log('client disconnected');
    });

    sock.on('error', function (err) {
        console.log('socket error - ', err);
    });
});

server.maxConnections = 10;
server.listen(3000, function () {
    console.log('echo server bound at port 3000');
});

效果是一样的。

net.Socket对象有一些方法,比如write可以写数据。还有一些事件,比如error、end、data等,看代码就能明白用法。还有一些属性,比如remoteAddress、remotePort。

我处理了data事件,data事件有一个参数,代表读到的数据。我在回调中直接使用net.Socket.write把数据原封不动发还给客户端。这是echo的一种实现。还有一种更方便的实现,就是调用net.Socket的pipe方法,Node.js net模块文档里提供的echoServer就是用的pipe,去看看吧。

客户端:

/**
 * Created by iwen on 16/11/5.
 */

var net = require("net");
var readline = require('readline');

console.log('type "exit" or "quit" to quit.');

// sock is an instance of net.Socket
var sock = net.connect({port: 3000}, function () {
    console.log('server connected');
    sock.setEncoding('utf8');
    sock.write('Hello Echo Server\r\n');
});

sock.on('data', function (data) {
    console.log('got data from server - ', data);
});

sock.on('end', function () {
    console.log('client disconnected');
});

sock.on('error', function (err) {
    console.log('socket error - ', err);
});

sock.on('close', function () {
    console.log('echo client was closed');
    process.exit(0);
});

var rl = readline.createInterface({
    input: process.stdin
});

function quitEcho() {
    rl.close();
    sock.end();
    console.log('quit echo client');
}

rl.on('line', function (cmd) {
    if (cmd.indexOf('quit') == 0 || cmd.indexOf('exit') == 0) {
        quitEcho();
    } else {
        sock.write(cmd + '\r\n');
    }
});

rl.on('SIGINT', quitEcho);

客户端代码稍长了一些。因为我想让echo更像echo,就调用readline模块来从标准输入读取数据来发送给客户端。readline的文档在这里:https://nodejs.org/api/readline.html。正如它的名字,Readline可以让你一行一行的读取一个流。比较常见的就是读取标准输入流。Readline有一些事件,我们用到的“line”事件,在一行数据就绪时会发射,带一个代表数据的参数。我监听line事件,在回调中调用net.Socket的write方法写入数据。当你在控制台输入“quit”或“exit”时,调用quitEcho退出。

net.connect方法可以连接到指定的服务器,它的原型如下:

net.connect(options[, connectionListener])

第一个参数是Object,用于指定和连接相关的选项,比如服务端的host、port等,如果不指定host,就默认用localhost作为服务端主机名。我在示例中只指定了端口。

net.connect返回net.Socket对象,一旦拿到了Socket实例,就可以用net.Socket来为所欲为了。我监听了data事件来接收服务端发挥的数据,监听close事件来退出进程。net.Socket的具体API,参考https://nodejs.org/api/net.html#net_class_net_socket

运行示例

评书里有句话,说时迟那时快,嗯哈,可以运行了。先执行“node echoServer.js”,然后执行“node echoClient.js”,就可以在echoClient的控制台界面输入一些内容了。效果如下图:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值