发送具有前导长度值的套接字数据


Sending sockets data with a leading length value

我想使用PHP套接字通过网络连接将JSON消息从PHP脚本发送到C#应用程序。

通常,对于二进制协议,每条消息的前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只接受字符串。那么,如何在PHP5.x中执行相同的前缀操作呢?

更新:我发布了一个关于如何处理从网络套接字接收到的此类前缀数据的后续问题。

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

因此,您需要将整数长度值编码为n un有符号整数的二进制表示,即4个字符(4个八位字节;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);

我想您可以使用pack()将字节数转换为二进制字符串。当你通过网络发送数据时,你可能需要使用格式"N"(无符号长,总是32位,大端字节顺序)进行转换。

这里有一个例子:

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