我正在将PHP函数转换为JS以与Node一起使用。
PHP 函数:
- 将部分形成的数据包作为参数
- 完成数据包
- 创建套接字
- 通过套接字发送数据包
- 从服务器读取响应代码
- 查找数组中的错误代码
- 将错误代码发送回调用方
我已经转换了大部分函数,除了读取服务器响应的位。
原创的PHP函数(注释是我对代码功能的理解。可能不正确)
function serverInteractive($buf) { // $buf = partially formed packet
$fp = fsockopen($ip, $port , $errno, $errstr, 5);
$rs = '';
if (!$fp) return $this -> fsockerror;
$packet = pack("s", (strlen($buf)+2)).$buf; // Finalizes the packet
fwrite($fp, $packet); // Sends the packet to the server.
// ----- Read Server Response START -----//
$len = unpack("v", fread($fp, 2));
$rid = unpack("c", fread($fp, 1));
for ($i = 0; $i < (($len[1] - 4) / 4); $i++) {
$read = unpack("i", fread($fp, 4));
$rs .= $read[1];
}
// ----- Read Server Response FINISH -----//
fclose($fp); // Closes the socket
$result = $this -> socketerrors[$rs];
// $socketerrors is an array of error messages.
return($result);
}
我的JavaScript版本
var net = require('net');
var submitPacket = function(packet) {
// Generate Final Packet
var p = pack('s', packet.length + 2) + packet;
// Create socket to Server
var serverSocket = net.createConnection(config.serverConfig.port,
config.serverConfig.host,
function() {
// Executes of connection is OK.
console.log("Connected to Server");
if (serverSocket.write(p, function() {
console.log("Buffer Flushed!");
})) {
console.log("Packet sent ok!");
} else {
console.log("There was a problem sending the packet!")
}
});
serverSocket.on('error', function(error) {
if (error) {
console.log(error);
}
});
serverSocket.on('data', function(data) {
if (data) {
console.log("Response: ", data);
// Need to put the error code generation
// here and fire a callback.
serverSocket.end();
}
});
}
当一切正常时,我从服务器得到的响应看起来像这样:
<Buffer 07 00 06 01 00 00 00>
当不正常时,看起来像这样:
<Buffer 0b 00 06 00 00 00 00 03 00 00 00>
任何建议将不胜感激。
更新1:这是我到目前为止想出的,但是生成的代码尚未定义。
serverdSocket.on('data', function(data) {
if (data) {
var response = toArrayBuffer(data);
var len = response.slice(0,2);
var rid = response.slice(0,1);
var rs = '';
for (var i = 0; i < ((len[1]-4) / 4); i++) {
var read = response.slice(0,4);
rs += read[1];
}
console.log("Code: ",rs);
}
更新2:PHP unpack 函数确实将二进制数据的缓冲区转换为数组。看起来我可以通过 JSON.stringify 然后 JSON.parse() 做同样的事情来让它进入数组。我现在有一个正确数据的数组对象,但函数的其余部分似乎没有复制原始数据。
我会试一试,尽管您实际上还没有说出您希望两个输入字符串的"Code:"输出是什么样子。我们将从 PHP 代码和 JavaScript 代码之间的差异开始。
让我们谈谈 PHP 代码中的这些行:
$len = unpack("v", fread($fp, 2));
$rid = unpack("c", fread($fp, 1));
现在,这些小fread()
函数调用实际上是从输入流/文件/任何内容中读取数据。底线是$len
从流的前两个字节获取其值,$rid
从第三个字节获取其值。
现在与 JavaScript 代码进行比较:
var len = response.slice(0,2);
var rid = response.slice(0,1);
我对这段代码有一些观察。首先,对slice()
的调用都对同一个类似数组的对象进行操作,从同一位置开始。所以rid
的价值将是错误的。其次,示例代码中从未使用 rid
的值,因此如果您从未真正需要它,则可以完全消除该行(这在 PHP 代码中无法做到)。第三个观察结果是,打电话给slice()
似乎矫枉过正。为什么不只在response
上使用方括号?
关于原始PHP代码的最后一个难题。查看构建$rs
的代码:
$rs .= $read[1];
看起来这是连续整数数据值的字符串串联。我已经在PHP工作了几年了,所以也许我错过了一些微妙之处,但这似乎是一件奇怪的事情。如果您能告诉我预期的输出代码应该是什么,那将有所帮助。
这就引出了数据本身。只是从 PHP 代码中的数据示例中猜测,看起来前两个字节是小端编码的 16 位缓冲区长度。下一个字节是rid
值,在两个示例中均为 6。然后看起来缓冲区的其余部分由 32 位小端值组成。当然,这是一个 WAG,但我只是在使用所提供的东西。
因此,下面是一些处理来自两个示例缓冲区的数据值的代码。对于第一个缓冲区,它打印Code: 1
,对于第二个Code: 03
。如果这些不是正确的值,那么让我知道预期的输出是什么,我会看看我是否可以让它工作。
function toArrayBuffer(buffer) {
var ab = new ArrayBuffer(buffer.length);
var view = new Uint8Array(ab);
for (var i = 0; i < buffer.length; ++i) {
view[i] = buffer[i];
}
return ab;
}
function serverSocketOnData(data)
{
if (data) {
var response = toArrayBuffer(data);
var len = response[0] + 256*response[1];
var rid = response[2]; // get rid of this line?
var rs = '';
for (var i = 3; i < len; i+=4) {
rs += response[i];
// if the 32-bit value could ever exceed 255, then use this instead:
// rs += response[i] + 256*response[i+1] +
// 256*256*response[i+2] + 256*256*256*response[i+3];
}
console.log("Code: ",rs);
}
}
function testArray(sourceArray)
{
var sourceBuffer = new Buffer(sourceArray);
console.log("source buffer");
console.log(sourceBuffer);
serverSocketOnData(sourceBuffer);
}
function main()
{
var sourceArray1 = [0x07,0x00,0x06,0x01,0x00,0x00,0x00];
var sourceArray2 = [0x0b,0x00,0x06,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00];
testArray(sourceArray1);
testArray(sourceArray2);
}
main();
你是否恰当地使用slice
?
当您在字符串上调用 slice 时,它会返回一个字符串。
var hello = "hello"
var hel = hello.slice(0, 3)
var h = hel[1]
var ello = hello.slice(1)