PHP到NodeJS转换不成功(TCP套接字问题)


PHP to NodeJS conversion not succeeding (TCP socket issue)

我正在尝试将以下PHP代码转换为Node.JS代码:

PHP

$TimeStart = microtime(true); // for read timeout purposes
// See http://wiki.vg/Protocol (Status Ping)
$Data = "'x00"; // packet ID = 0 (varint)
$Data .= "'x04"; // Protocol version (varint)
$Data .= Pack( 'c', StrLen( $this->ServerAddress ) ) . $this->ServerAddress; // Server (varint len + UTF-8 addr)
$Data .= Pack( 'n', $this->ServerPort ); // Server port (unsigned short)
$Data .= "'x01"; // Next state: status (varint)
$Data = Pack( 'c', StrLen( $Data ) ) . $Data; // prepend length of packet ID + data
fwrite( $this->Socket, $Data ); // handshake
fwrite( $this->Socket, "'x01'x00" ); // status ping
$Length = $this->ReadVarInt( ); // full packet length
if( $Length < 10 )
{
    return FALSE;
}
fgetc( $this->Socket ); // packet type, in server ping it's 0
$Length = $this->ReadVarInt( ); // string length
$Data = "";
do
{
    if (microtime(true) - $TimeStart > $this->Timeout)
    {
        //exception
    }
    $Remainder = $Length - StrLen( $Data );
    $block = fread( $this->Socket, $Remainder ); // and finally the json string
    // abort if there is no progress
    if (!$block)
    {
        //exception
    }
    $Data .= $block;
} while( StrLen($Data) < $Length );

这是我认为它是,但显然它不一样,我没有得到任何数据返回。

var socket = new net.Socket();
socket = net.connect(port, host, function(){
    console.log('Connected');
    /*
    Returns data but protocol is not correctly folllowed
    -----------------------------------------------------*/
    var PACKET_HEAD = new Buffer([
        0, // Packet ID 0
        4 // Version 4 (1.7.2), 5 is 1.7.6
    ]);
    var PACKET_PORT = new Buffer(2);
    var PACKET_NEXTSTATE = new Buffer([1]);
    var PACKET_STATUS_REQ = new Buffer([1, 0]);

    host = new Buffer(host);
    var addrLen = new Buffer(varint.encode(host.length));
    PACKET_PORT.writeUInt16BE(port, 0);
    var packetLength = 2 + addrLen.length + host.length + 2 + 1;
    var lengthBuffer = new Buffer(varint.encode(packetLength));
    var packet = Buffer.concat([
        lengthBuffer,
        PACKET_HEAD,
        addrLen,
        host,
        PACKET_PORT,
        PACKET_NEXTSTATE,
        PACKET_STATUS_REQ
    ], packetLength + 3);
    socket.write(packet);
    /*
    TRY 1
    ------*/
    var packet;
    packet = "'x00";
    packet += "'x04";
    packet += bufferpack.pack('c', host.length.toString()) + host;
    packet += bufferpack.pack('n', port.toString());
    packet += "'x01";
    packet = bufferpack.pack('c', packet.length.toString()) + packet;
    socket.write(packet);
    socket.write("'x01'x00");

    /*TRY 2
    -------*/
    var packet;
    packet = packData(
        ''x00'x00' 
        + packData(host.toString('utf8'))
        + packPort(port)
        + ''x01'
    );
    socket.write(packet);
    socket.write(packData(''x00'));
});

socket.on('error', function(err){
    console.log(errorHandler(err));
    socket.end();
});
socket.on('data', function(data){
    console.log(data);
    socket.end();
});
setTimeout(function(){
    console.log("Timeout");
    socket.end();
    socket.destroy();
}, 1000);

function char(value) {
    return value.toString().charCodeAt(0);
}
function packData(data) {
    return varint.encode(data.length) + data;
}
function packPort(data) {
    return bufferpack.pack('>H', data.toString());
}

我尝试了许多方法来复制php代码到nodejs端,最终使用模仿包行为的库(bufferpack)。

我想我错过了什么,但我不知道它是什么

可能有点晚了,但我已经让你的代码为我工作了。

我使用的模块:https://github.com/ryanrolds/bufferpack

安装使用:NPM install bufferpack

这是纯代码(复制)

var _connection;
var connect = function(port, host, callback) {
    _connection = new net.Socket();
    _connection.connect(port, host, function() {
        system.log('Connected to the server, authenticating now.');
        var PACKET_HEAD = new Buffer([
            0, // Packet ID 0
            47 // Version 4 (1.7.2), 5 is 1.7.6
        ]);
        var PACKET_PORT = new Buffer(2);
        var PACKET_NEXTSTATE = new Buffer([1]);
        var PACKET_STATUS_REQ = new Buffer([1, 0]);

        host = new Buffer(host);
        var addrLen = new Buffer(varint.encode(host.length));
        PACKET_PORT.writeUInt16BE(port, 0);
        var packetLength = 2 + addrLen.length + host.length + 2 + 1;
        var lengthBuffer = new Buffer(varint.encode(packetLength));
        var packet = Buffer.concat([
            lengthBuffer,
            PACKET_HEAD,
            addrLen,
            host,
            PACKET_PORT,
            PACKET_NEXTSTATE,
            PACKET_STATUS_REQ
        ], packetLength + 3);
        _connection.write(packet);
        /*
        TRY 1
        ------*/
        var packet;
        packet = "'x00";
        packet += "'x04";
        packet += bufferpack.pack('c', host.length.toString()) + host;
        packet += bufferpack.pack('n', port.toString());
        packet += "'x01";
        packet = bufferpack.pack('c', packet.length.toString()) + packet;
        _connection.write(packet);
        _connection.write("'x01'x00");

        /*TRY 2
        -------*/
        var packet;
        packet = packData(
            ''x00'x00' 
            + packData(host.toString('utf8'))
            + packPort(port)
            + ''x01'
        );
        _connection.write(packet);
        _connection.write(packData(''x00'));
    });
    _connection.on('error', function(err){
        system.log(err);
        _connection.end();
    });
    _connection.on('data', function(data){
        system.log(data);
    });
};
exports.connect = connect;
function packData(data) {
    return varint.encode(data.length) + data;
}
function packPort(data) {
    return bufferpack.pack('>H', data.toString());
}

My github repo:https://github.com/AtlasDev/NodeCraft

这部分在lib/connection.js

希望这仍然有帮助,AtlasDev