2012-03-16 40 views
4

我想通過網絡連接使用PHP Sockets將PHP腳本的JSON消息發送到C#應用程序。發送具有前導長度值的套接字數據

Usually, for binary protocols,每條消息的前4個字節必須是一個表示消息長度(多少字節)的整數。

在C#中我每前綴消息,告訴消息的長度如下整數:

byte[] msgBytes = UTF8Encoding.UTF8.GetBytes("A JSON msg");    
byte[] prefixBytes = BitConverter.GetBytes(msgBytes.Length); 
byte[] msgToSend = new byte[prefixBytes.Length + msgBytes.Length]; 
Buffer.BlockCopy(prefixBytes, 0, msgToSend, 0, prefixBytes.Length); 
Buffer.BlockCopy(msgBytes, 0, msgToSend, prefixBytes.Length, msgBytes.Length); 

據我瞭解,在PHP函數socket_send只接受字符串。那麼,我怎樣才能在PHP 5.x中做同樣的前綴?

更新:我發佈了一個follow-up question關於如何處理從網絡套接字接收到這樣的前綴數據。

回答

5

在PHP中,字符串是二進制的。

因此,您需要將整數長度值作爲 n un 有符號整數的二進制表示形式編碼爲4字符(4 Octets; 32位)字符串。見pack

# choose the right format according to your byte-order needs: 

l signed long (always 32 bit, machine byte order) 
L unsigned long (always 32 bit, machine byte order) 
N unsigned long (always 32 bit, big endian byte order) 
V unsigned long (always 32 bit, little endian byte order) 

$string = pack('l', $length); 
5

我想你可以使用pack()到的字節數轉換爲二進制字符串。在通過網絡發送數據時,您可能需要使用格式「N」(無符號長整型,始終爲32位,大端字節順序)進行轉換。

下面是一個例子:

$s="Hello World"; 
$length=pack("N",strlen($s)); 
socket_send($sock,$length.$s,4+strlen($s)); 
+2

你爲什麼要使用 「N」(Big Endian字節序)? – Mike 2012-03-16 20:33:30

+2

@Mike:請諮詢您的.Net產品文檔,哪種類型適用於此。可能是一個32位有符號整數,其字節順序取決於您的機器。同時檢查你使用的協議的規格。所以'L','N'和'V'很可能是錯誤的(即使我在回答中有他們,你需要仔細檢查你使用的規格)。 – hakre 2012-03-16 20:52:13

+2

@hakre感謝您的幫助。看起來,c#應用程序使用小端,所以'V'應該是最好的選擇,對吧? – Mike 2012-03-16 21:33:11