繁体   English   中英

Node.js ReadLine没有等待套接字连接的完整一行?

[英]Node.js ReadLine not waiting for a full line on socket connections?

我试图使用Node.js的ReadLine套接字 ,如下所示:

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

this.streamServer = net.createServer(function (socket) {
    var i = rl.createInterface(socket, socket);
    i.on('line', function (line) {
        socket.write(line);
    });
});
this.streamServer.maxConnections = 1;
this.streamServer.listen(7001);

当我远程登录到端口7001并开始输入文本时,它会在我按下回车之前立即回复给我。

为什么ReadLine不等待全线?

我也尝试了.question() ,我得到了相同的结果......在收到任何数据时触发回调,而不等待行尾字符。


编辑:这甚至更奇怪。 当我使用Windows telnet客户端进行测试时,我得到了上面提到的行为。 但是,如果我使用PuTTY作为客户端进行测试,ReadLine即使在Windows上也能正常工作。 我做了一些数据包捕获。 也许有人可以对此有所了解? 未缩进的行是来自客户端的数据。 缩进行是服务器回复。

使用Windows Telnet

00000000  61                                               a
    00000000  61                                               a
00000001  62                                               b
    00000001  62                                               b
00000002  63                                               c
    00000002  63                                               c
00000003  64                                               d
    00000003  64                                               d
00000004  65                                               e
    00000004  65                                               e
00000005  66                                               f
    00000005  66                                               f
00000006  67                                               g
    00000006  67                                               g
00000007  68                                               h
    00000007  68                                               h
00000008  69                                               i
    00000008  69                                               i
00000009  6a                                               j
    00000009  6a                                               j
0000000A  6b                                               k
    0000000A  6b                                               k
0000000B  6c                                               l
    0000000B  6c                                               l
0000000C  6d                                               m
    0000000C  6d                                               m
0000000D  6e                                               n
    0000000D  6e                                               n
0000000E  6f                                               o
    0000000E  6f                                               o
0000000F  70                                               p
    0000000F  70                                               p
00000010  0d 0a                                            ..
    00000010  0d 0a                                            ..
00000012  0d 0a                                            ..
    00000012  0d 0a                                            ..
00000014  0d 0a                                            ..
    00000014  0d 0a                                            ..
00000016  61                                               a
    00000016  61                                               a
00000017  73                                               s
    00000017  73                                               s
00000018  64                                               d
    00000018  64                                               d
00000019  66                                               f
    00000019  66                                               f
0000001A  0d 0a                                            ..
    0000001A  0d 0a                                            ..
0000001C  61                                               a
    0000001C  61                                               a
0000001D  73                                               s
    0000001D  73                                               s
0000001E  64                                               d
    0000001E  64                                               d
0000001F  66                                               f
    0000001F  66                                               f
00000020  0d 0a                                            ..
    00000020  0d 0a                                            ..

使用PuTTY

00000000  ff fb 1f ff fb 20 ff fb  18 ff fb 27 ff fd 01 ff ..... .. ...'....
00000010  fb 03 ff fd 03                                   .....
    00000000  ef bf bd ef bf bd 1f ef  bf bd ef bf bd 20 ef bf ........ ..... ..
    00000010  bd ef bf bd 18 ef bf bd  ef bf bd 27 ef bf bd ef ........ ...'....
    00000020  bf bd 01 ef bf bd ef bf  bd 03 ef bf bd ef bf bd ........ ........
    00000030  03                                               .
00000015  61 62 63 64 65 66 67                             abcdefg
0000001C  0d 0a                                            ..
    00000031  61 62 63 64 65 66 67                             abcdefg
    00000038  0d 0a                                            ..
0000001E  61 73 64 66                                      asdf
00000022  0d 0a                                            ..
    0000003A  61 73 64 66                                      asdf
    0000003E  0d 0a                                            ..
00000024  61 73 64 66                                      asdf
00000028  0d 0a                                            ..
    00000040  61 73 64 66                                      asdf
    00000044  0d 0a                                            ..
0000002A  0d 0a                                            ..
    00000046  0d 0a                                            ..

这是node.js中的一个错误,ReadLine的接口在每个'data'事件上调用_normalWrite(),而_normaWrite有一个注释,它应该尝试在换行符上打破,但是目前它只调用_onLine()

根据这一点,我们应该为您解决这个问题:

i._normalWrite = function(b) {
    if(b == undefined) {
        return;
    }
    if(!this._line_buffer) {
        this._line_buffer = '';
    }
    this._line_buffer += b.toString();
    if(this._line_buffer.indexOf('\n') !=-1 ) {
        var lines = this._line_buffer.split('\n');
        // either '' or the unfinished portion of the next line
        this._line_buffer = lines.pop();
        lines.forEach(function(line) {
            this._onLine(line + '\n');
        }, this);
    }
};

我没有测试过这个,它也可能需要考虑\\r 如果它适用于你,请告诉我,如果是这样,那么我们中的一个人应该发送节点拉取请求。

我的问题的另一种解决方案......每次从流中获得新行时,我只需要获得某种行事件。 由于我不需要readline附带的所有其他东西,我在这里找到了TooTallNate的这个片段: https ://gist.github.com/1785026

/**
 * By TooTallNate, originally posted at https://gist.github.com/1785026
 * A quick little thingy that takes a Stream instance and makes
 * it emit 'line' events when a newline is encountered.
 *
 *   Usage:
 *   ‾‾‾‾‾
 *  emitLines(process.stdin)
 *  process.stdin.resume()
 *  process.stdin.setEncoding('utf8')
 *  process.stdin.on('line', function (line) {
 *    console.log(line event:', line)
 *  })
 *
 */

function emitLines (stream) {
  var backlog = ''
  stream.on('data', function (data) {
    backlog += data
    var n = backlog.indexOf('\n')
    // got a \n? emit one or more 'line' events
    while (~n) {
      stream.emit('line', backlog.substring(0, n))
      backlog = backlog.substring(n + 1)
      n = backlog.indexOf('\n')
    }
  })
  stream.on('end', function () {
    if (backlog) {
      stream.emit('line', backlog)
    }
  })
}

这是作为对Nathan的拉动请求的评论发布在这里: https//github.com/joyent/node/pull/3059

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM