2012-03-16 35 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