简体   繁体   English

对于Node.js socket来说,php的fgetc()相当于什么?

[英]What is the equivalent of php's fgetc() for Node.js socket's?

What is the Node.js equivalent of the fgetc() function in php? 什么是PHP中fgetc()函数的Node.js等价物? And how would I apply it to a socket? 我将如何将其应用于套接字?

I'm working on a node.js port of this php script: http://code.google.com/p/bf2php/source/browse/trunk/rcon/BF2RConBase.class.php 我正在开发这个php脚本的node.js端口: http//code.google.com/p/bf2php/source/browse/trunk/rcon/BF2RConBase.class.php

Basically it uses sockets to connect to Battlefield 2 based game servers. 基本上它使用套接字连接到基于战地2的游戏服务器。 The function I'm looking at is: 我正在看的功能是:

protected function read($bare = false) {
    $delim = $bare ? "\n" : "\x04";
    for($buffer = ''; ($char = fgetc($this->socket)) != $delim; $buffer .= $char);
    return trim($buffer);
}

Its supposed to grab the first line directly from the socket (from what I gather) one character at a time up til the '\\n'. 它应该直接从套接字(从我收集的信息)中抓取第一行一次一个字符直到'\\ n'。 I'm assuming the output is used for grabbing an encryption salt. 我假设输出用于获取加密盐。 The function is called in the socket connect event as part of the code that generates the encrypted password needed to login. 该函数在套接字连接事件中被调用,作为生成登录所需加密密码的代码的一部分。 Can anyone show me what a Node.js equivalent of this function might look like? 任何人都可以告诉我这个函数的Node.js等价物是什么样的吗?

The docs have an excellent example of how to connect to a server over the network. 这些文档有一个很好的例子,说明如何通过网络连接到服务器。

var net = require('net');
var client = net.connect({port: 8124},
    function() { //'connect' listener
  console.log('client connected');
  client.write('world!\r\n');
});
client.on('data', function(data) {
  console.log(data.toString());
  client.end();
});
client.on('end', function() {
  console.log('client disconnected');
});

Simply change the data event handler to buffer incoming data until you've recieved the information you want. 只需更改data事件处理程序即可缓冲传入的数据,直到您收到所需的信息为止。

To do that, you'll want to know how to use a Buffer . 为此,您需要知道如何使用Buffer


Here's a concrete example of how to buffer data from a stream and parse out messages delimited by a specific character. 下面是如何缓冲流中的数据并解析由特定字符分隔的消息的具体示例。 I notice in the linked PHP that the protocol you're trying to implement delimts messages with a EOT (0x04) character. 我注意到在链接的PHP中,您尝试实现的协议使用EOT(0x04)字符来分隔消息。

var net = require('net');


var max = 1024 * 1024 // 1 MB, the maximum amount of data that we will buffer (prevent a bad server from crashing us by filling up RAM)
    , allocate = 4096; // how much memory to allocate at once, 4 kB (there's no point in wasting 1 MB of RAM to buffer a few bytes)
    , buffer=new Buffer(allocate) // create a new buffer that allocates 4 kB to start
    , nread=0 // how many bytes we've buffered so far
    , nproc=0 // how many bytes in the buffer we've processed (to avoid looping over the entire buffer every time data is received)
    , client = net.connect({host:'example.com', port: 8124}); // connect to the server

client.on('data', function(chunk) {
    if (nread + chunk.length > buffer.length) { // if the buffer is too small to hold the data
        var need = Math.min(chunk.length, allocate); // allocate at least 4kB
        if (nread + need > max) throw new Error('Buffer overflow'); // uh-oh, we're all full - TODO you'll want to handle this more gracefully

        var newbuf = new Buffer(buffer.length + need); // because Buffers can't be resized, we must allocate a new one
        buffer.copy(newbuf); // and copy the old one's data to the new one
        buffer = newbuf; // the old, small buffer will be garbage collected
    }

    chunk.copy(buffer, nread); // copy the received chunk of data into the buffer
    nread += chunk.length; // add this chunk's length to the total number of bytes buffered

    pump(); // look at the buffer to see if we've received enough data to act
});

client.on('end', function() {
    // handle disconnect
});


client.on('error', function(err) {
    // handle errors
});


function find(byte) { // look for a specific byte in the buffer
    for (var i = nproc; i < nread; i++) { // look through the buffer, starting from where we left off last time
        if (buffer.readUInt8(i, true) == byte) { // we've found one
            return i;
        }
    }
}
function slice(bytes) { // discard bytes from the beginning of a buffer
    buffer = buffer.slice(bytes); // slice off the bytes
    nread -= bytes; // note that we've removed bytes
    nproc = 0; // and reset the processed bytes counter
}

function pump() {
    var pos; // position of a EOT character

    while ((pos = find(0x04)) >= 0) { // keep going while there's a EOT (0x04) somewhere in the buffer
        if (pos == 0) { // if there's more than one EOT in a row, the buffer will now start with a EOT
            slice(1); // discard it
            continue; // so that the next iteration will start with data
        }
        process(buffer.slice(0,pos)); // hand off the message
        slice(pos+1); // and slice the processed data off the buffer
    }
}

function process(msg) { // here's where we do something with a message
    if (msg.length > 0) { // ignore empty messages
        // here's where you have to decide what to do with the data you've received
        // experiment with the protocol
    }
}

Completely untested, so there's likely errors. 完全未经测试,因此可能存在错误。 The main thing to gather here is that as data arrives, you buffer it in memory. 这里收集的主要内容是,当数据到达时,您将其缓冲在内存中。 Once you find a delimiter character in your buffer, you can process the message. 在缓冲区中找到分隔符后,您可以处理该消息。

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

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