PHP通过socket编程传递C结构体数据

4
如何制作一个 PHP 套接字客户端,需要执行 `socket_sendto` 到以下具有结构的 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结构体对象:

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 socket服务器:

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

那么我怎样才能使用PHP发送dms_aufHead数据呢?


根据c socket服务器的开发者提议,他们正在使用以下c代码将值发送到c socket服务器:

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

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

如果(例如)$rz只有3个字符(对于此情况),而不是期望的13个字符,我应该输出什么给PHP?

3个回答

3
你需要按正确的顺序使用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
最好是将数据序列化成像JSON这样的文本格式(或者使用pack函数)在发送数据之前。收到后,您可以将其反序列化为适当的数据结构。

1

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

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

另一方面,如果服务器尚不存在,则有可用的C/C++库可以解析PHP序列化数据结构(请参见this SO topic),或者如果需要支持更正式的协议,则可以查看SOAP。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接