2014-04-01 30 views
5

我正在將PHP函數轉換爲JS以便與Node一起使用。在Node.js中讀取套接字連接響應

PHP函數:

  • 處於部分形成的分組需要作爲ARG
  • 定型包
  • 創建一個套接字
  • 在插座
  • 將分組發送讀取響應來自服務器的代碼
  • 查找數組中的錯誤代碼
  • 發送錯誤代碼返回給調用者

我有大部分的功能的轉換除了用於讀取服務器響應該位。

原始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解壓函數確實將二進制數據的緩衝區轉換爲數組。它看起來像我可以通過JSON.stringify做同樣的事情,然後JSON.parse()將其放入數組中。我現在有一個正確數據的數組對象,但函數的其餘部分似乎並不複製原始數據。

+0

'unpack()'PHP函數將二進制數據緩衝區轉換爲數組。你必須在JavaScript中做同樣的事情。然後你可以檢查數據字節到你的心臟的內容。有一個類似的問題已經在這裏解答:http://stackoverflow.com/questions/8609289/convert-a-binary-nodejs-buffer-to-javascript-arraybuffer –

+0

它看起來像我可以使用JSON.stringify方法來創建一個從緩衝區aray。用新的代碼更新了代碼。但RS仍然沒有。嘗試一些其他的東西... – Andrew

+0

我越來越絕望。絕對會向某人提供解決方案。請給我發電子郵件[email protected] – Andrew

回答

0

您是否正確使用slice

當你在一個字符串上調用切片時,它會返回一個字符串。

var hello = "hello" 
var hel = hello.slice(0, 3) 
var h = hel[1] 
var ello = hello.slice(1) 
+0

切片可能是直接在緩衝區上使用的錯誤方法。我有一段時間是使用上面提到的JSON函數將緩衝區轉換爲數組。這似乎工作。但我仍然無法解決如何讓錯誤代碼號碼生成工作。 – Andrew

2

我會試一試,儘管你還沒有真正說過你想讓「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(); 
+0

感謝您花時間對此問題進行如此廣泛的評論。我有人與我聯繫,他重寫了所有的東西,所以它使用讀取原始二進制數據的緩衝區在JS中本地工作。你是對的。儘管閱讀了文檔,但我並不完全理解PHP函數的功能。我以前從來沒有必須處理套接字原始數據包或緩衝區。儘管所提供的代碼並不能可靠地解決問題(不是您的錯誤),但它是一個絕佳的起點,並且是一個了不起的學習練習。非常感謝您爲此付出的時間。 – Andrew