php通过套接字编程传递c struct数据

时间:2010-10-22 03:55:23

标签: php c linux sockets

如何使一个需要执行socket_sendto的php套接字客户端到具有以下结构的linux C套接字服务器

typedef struct
{
  UI2             todo;   
  char            rz[LNG_RZ + 1]; 
  char            saId[LNG_SAT_ID + 1]; 
  char            user[LNG_USER + 1]; 
  char            lang[LANGLEN + 1]; 
  SI4             result;       
  UI4             socket;  
  char            text[LNG_ALLG + 1]; 
  char            filename[MAX_PATHLEN];
}  dmsAuf_Head;        

显然,已知PHP不支持struct如何使用php

将c数据传递给socket

我知道使用以下方法制作c struct对象有一个技巧:

class dmsAuf_Head {
  public            todo;            
  public            rz    
  public            saId    
  public            user    
  public            lang    
  public            result;                         
  public            socket;        
  public            text   
  public            filename 
}

$obj = new dmsAuf_Head();

但这不会考虑属性的大小?任何推荐?


如何在发送之前序列化所有内容???

正如c socket服务器的开发人员所建议的那样,他们使用以下c代码将值发送到c套接字服务器:

 rval = send(dms_aufHead->socket, (char *) dms_aufHead, sizeof(dmsAuf_Head), 0);

那么如何使用php发送dms_aufHead数据呢?


正如c socket服务器的开发人员所建议的那样,他们使用以下c代码将值发送到c套接字服务器:

rval = send(dms_aufHead->socket, (char *) dms_aufHead, sizeof(dmsAuf_Head), 0);

那么如何使用php发送dms_aufHead数据呢?

如果(例如)$ rz只有3个char(对于这种情况)而不是13个char作为所需长度怎么办?我应该为PHP输出什么?

3 个答案:

答案 0 :(得分:2)

您需要按正确的顺序fwrite数据。 pack功能非常有用。

http://us2.php.net/pack

fwrite($sock, pack('v', 0x1234)); // send a 16 bit integer

当然,您必须注意C结构的构建方式(填充等),目标机器期望的字节顺序等等。

由于这一切,两个系统通常更好地简单地读取/写入顺序所需的数据并手动填写结构(逐个字段),而不是试图将结构本身作为一个大的fread / fwrite块。在PHP方面,它可能看起来像:

class dmsAuf_Head {
  public            $todo;            
  public            $rz;    
  public            $saId;    
  public            $user;    
  public            $lang;    
  public            $result;                         
  public            $socket;        
  public            $text;   
  public            $filename; 

  public function send($sock)
  {
    fwrite($sock, pack('v', $this->todo));
    // .. fwrite the rest
  }
}

$foo = new dmsAuf_Head();
$foo->send($sock);

(请注意,如果使用多个参数,则可以构建单个打包字符串并一次性发送。)

答案 1 :(得分:0)

如果您在通过线路发送数据之前将数据序列化为JSON(或者可能使用pack功能)等文本格式,那将是最好的。收到后,您可以将其反序列化为适当的数据结构。

答案 2 :(得分:0)

没有像“c struct”这样的数据协议/格式,由C编译器如何存储这些数据 - 以及C程序的程序员来决定如何填充/从结构中检索值。即使您使用相同的结构在C中编写客户端,您也需要将其转换为不同的表示形式以将其传输到服务器。 PHP也是如此 - 尽管'serialize'提供了一种内置机制,用于创建PHP数据结构的可移植表示。

您需要编写PHP代码来创建服务器可以处理的数据的表示 - 这与服务器在内部存储/操作数据如何几乎没有关系。为了使服务器存在,它必须具有以某种格式解析数据的能力 - 找出那种格式并相应地编写PHP。

OTOH如果服务器尚不存在,那么有可用的C / C ++库将解析PHP序列化数据结构(参见this SO topic)或者是否需要支持更正式的协议,那么看看肥皂。