【问题标题】:php passing c struct data throught socket programmingphp通过socket编程传递c struct数据
【发布时间】:2011-04-28 23:16:34
【问题描述】:

如何制作一个需要对具有以下结构的linux C socket服务器执行socket_sendto的php socket客户端

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 数据传递给套接字

我知道使用下面的方法制作 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 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 输出什么?

【问题讨论】:

    标签: php c linux sockets


    【解决方案1】:

    您需要以正确的顺序fwrite 数据。 pack 函数会很有用。

    http://us2.php.net/pack

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

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

    正因为如此,两个系统通常最好按顺序读取/写入所需的数据并手动(逐个字段)填充结构,而不是尝试将结构本身作为一个大文件进行读取/写入堵塞。在 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);
    

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          猜你喜欢
          • 2018-02-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多