【发布时间】:2015-01-03 07:23:44
【问题描述】:
我需要开发一个 PHP 服务器套接字和一个 C 客户端套接字,反之亦然。
我对 C 语言中的 TCP 套接字及其概念非常了解。
我被困在最后一件事上。
我可以从 C 客户端套接字发送整个结构如下
typedef struct _test {
char str[32];
char c;
int i;
float f;
}test;
//Some Coding ...
memset(&t,'\0',sizeof(test));
strcpy(t.str,"Sunny"); //String
t.c = 'M'; //Char
t.i = 26; //Integer
t.f = 98.8; //Float
//Send test STRUCT to server
if(send(sockfd,(void *)&t,sizeof(t),0) < 0)
{
perror("Send failed ");
exit(0);
}
//一些编码...
我在 PHP 服务器套接字上接收到这个结构如下
...
$client = socket_accept($socket);
$input = socket_read($client, 1024);
$arr = unpack("Z32Str/a1Chr/iInt/fFlt", $input);
echo $arr['Str']; //Print String
echo $arr['Chr']; //Print Char
echo $arr['Int']; //Print Int
echo $arr['Flt']; //Print Float
...
我正在正确获取字符串和字符,但没有正确获取整数和浮点数,我确信它的网络托管字节顺序(小端序,大端序)问题。
即我得到整数 value 为 436207616
谁能告诉我如何在 PHP 中实现与 ntohl 和 ntohs 等效的功能。
附: :- 我是 PHP 新手...请帮助
【问题讨论】:
-
问题很可能不是字节顺序,而是结构填充。请记住,大多数 C 编译器填充它们的结构,以便字段从偶数地址开始。在结构中的字符之后,很可能有一个您在 PHP 代码中未处理的 3 字节填充字段。您可以通过在 C 源代码中打印
sizeof(struct _test)来轻松验证这一点,我敢打赌它是 44 而不是 41。 -
ya joachim,没错...我正在进一步检查...但是您能否建议如何在 PHP 中为此类情况编写解包函数,就像 php 中的新手一样。
-
大多数编译器支持结构的打包,以最小化填充或完全删除它。在 PHP 中解包时,您可以使用填充,但在
'Chr'之后添加三个虚拟字节。请注意,更改结构会更改填充。 -
添加到 Joachim,我会在应用程序启动时将空结构的大小发送到服务器,这样您就可以确定它是您在 PHP 端所期望的。
-
您可以强制编译器不添加填充,也可以按以下顺序重新组织结构:str、i、f、c