[英]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.