任何一款拥有socket操作能力的语言都有一个专门用于组包的函数,php也不例外!

用了很久php了却很少有机会用php进行一些二进制操作。 最近用php写一个socket客户端连接一个用C++语言开发的游戏服务端。 服务器端开发人员使用了二进制的形式来定义协议的格式。协议格式如下:

包头(2bytes)+加密(1byte)+命令码(2bytes)+帧内容

1.包头的内容是记录帧内容的长度;
2. 加密:0表示不加密,1表示加密;
3. 命令码为服务端命令识别符号;

一开始不了解php原来有pack可以来组装二进制包, 走了弯路,让服务端开发人员用C语言帮忙开发了的几个内存操作函数,按照协议规则返回二进制包,然后我将这几个方法编译成一组扩展函数供php使用。
   
    话归正题,本文是介绍如何使用pack和unpack这两个方法的。php官方手册举例太少,不能很容易理解,特别是那些格式化参数的使用。

转摘的参数中文说明:

pack/unpack 的摸板字符字符 含义
a 一个填充空的字节串
A 一个填充空格的字节串
b 一个位串,在每个字节里位的顺序都是升序
B 一个位串,在每个字节里位的顺序都是降序
c 一个有符号 char(8位整数)值
C 一个无符号 char(8位整数)值;关于 Unicode 参阅 U
d 本机格式的双精度浮点数
f 本机格式的单精度浮点数
h 一个十六进制串,低四位在前
H 一个十六进制串,高四位在前
i 一个有符号整数值,本机格式
I 一个无符号整数值,本机格式
l 一个有符号长整形,总是 32 位
L 一个无符号长整形,总是 32 位
n 一个 16位短整形,“网络”字节序(大头在前)
N 一个 32 位短整形,“网络”字节序(大头在前)
p 一个指向空结尾的字串的指针
P 一个指向定长字串的指针
q 一个有符号四倍(64位整数)值
Q 一个无符号四倍(64位整数)值
s 一个有符号短整数值,总是 16 位
S 一个无符号短整数值,总是 16 位,字节序跟机器芯片有关
u 一个无编码的字串
U 一个 Unicode 字符数字
v 一个“VAX”字节序(小头在前)的 16 位短整数
V 一个“VAX”字节序(小头在前)的 32 位短整数
w 一个 BER 压缩的整数
x 一个空字节(向前忽略一个字节)
X 备份一个字节
Z 一个空结束的(和空填充的)字节串
@ 用空字节填充绝对位置

string pack ( string $format [, mixed $args [, mixed $...]] )

一些规则:
1.每个字母后面都可以跟着一个数字,表示 count(计数),如果 count 是一个 * 表示剩下的所有东西。
2.如果你提供的参数比 $format 要求的少,pack 假设缺的都是空值。如果你提供的参数比 $format 要求的多,那么多余的参数被忽略。

下面还是用例子来说明用法会容易理解一点:

关于Pack:

下面的第一部分把数字值包装成字节:
$out = pack("CCCC", 65, 66, 67, 68);      # $out 等于"ABCD"
$out = pack("C4", 65, 66, 67, 68);         # 一样的东西

下面的对 Unicode 的循环字母做同样的事情:
  $foo = pack("U4", 0x24b6, 0x24b7, 0x24b8, 0x24b9);

下面的做类似的事情,增加了一些空:
  $out = pack("CCxxCC", 65, 66, 67, 68);      # $out 等于 "AB\0\0CD"

打包你的短整数并不意味着你就可移植了:
  $out = pack("s2", 1, 2);        
# 在小头在前的机器上是 "\1\0\2\0"
# 在大头在前的机器上是 "\0\1\0\2"

在二进制和十六进制包装上,count 指的是位或者半字节的数量,而不是生成的字节数量:
  $out = pack("B32", "...");
    $out = pack("H8", "5065726c");         # 都生成“Perl”

a 域里的长度只应用于一个字串:
  $out = pack("a4", "abcd", "x", "y", "z");      # "abcd"

要绕开这个限制,使用多倍声明:
  $out = pack("aaaa",    "abcd", "x", "y", "z");   # "axyz"
   $out = pack("a" x 4,   "abcd", "x", "y", "z");   # "axyz"

a 格式做空填充:
  $out = pack("a14", "abcdefg");         # " abcdefg\0\0\0\0\0\0"

关于unpack:

array unpack ( string $format, string $data )

$data = "010000020007";
unpack("Sint1/Cchar1/Sint2/Cchar2",$data);

## array('int1'=>1, 'char1'=>'0','int2'=>2,'char2'=>7);

最后本文开头讲到的协议使用pack/unpack 举例程序代码为 :


$lastact   = pack('SCSa32a32',0x0040, 0x00, 0x0006, $username, $passwd );

unpack('Sint1/Cchar1/Sint2/Cchar2/',$lastmessage);

原文链接:http://blog.sina.com.cn/s/blog_3eba8f1c0100nq9r.html
socket 相关方法帮助文档 http://php.net/manual/en/book.sockets.php

转载于:https://www.cnblogs.com/yimu/archive/2012/12/04/2801099.html

socket中pack 和 unpack 的使用相关推荐

  1. PHP中的pack和unpack函数

    转载请注明文章出处:https://tlanyan.me/php-pack-a... PHP有两个重要的冷门函数:pack和unpack.在网络编程,读写图像文件等场景,这两个函数几乎必不可少.鉴于文 ...

  2. PHP: chr和pack、unpack那些事

    为什么80%的码农都做不了架构师?>>>    PHP是一门很灵活的语言.正因为它太灵活了,甚至有些怪异,所以大家对它的评价褒贬不一.其实我想说的是,任何一门语言都有它自身的哲学,有 ...

  3. 解释一下pack和unpack

    pack/unpack runbase Framwork用pack和unpack来保存用户上次操作的值,用户上次操作的值会存在SysLastValue表中,这个功能确实蛮酷,不过今天差点被这个东西给整 ...

  4. python中pack函数_关于pack()函数的文章推荐10篇 - pack

    php读写二进制文件可以使用pack和unpack函数. 今天要处理一个二进制文件的问题,所以需要用一下,特意了解一下pack的用法,unpack用法与此类似. 简单来说,pack函数就是给一个目标格 ...

  5. python中pack什么意思_Python struct.pack如何理解其原理

    def setUTF(self, value): """ """ tag = '>h' if self.endian == HIGHT ...

  6. python的pack和unpack用法

    python的pack和unpack用法 pack和unpack在处理二进制流中比较常用的封包.解包格式 按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流) pack(fm ...

  7. 简单分析一下socket中的bind

    在最开始接触bind的时候,只是在写基于tcp的server端的时候,知道在listen之前需要先bind一下,用来确保socket能在某个固定的端口监听.而bind的时候,函数参数中的端口填自己将要 ...

  8. Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)

    为了方便讲解,我们把 DataOutputstream dout = new DataOutputStream(new BufferedOutputStream(mySocket.getOutputS ...

  9. PYTHON__关于Socket中的Select使用理解

    关于Socket中的Select使用理解 以下是代码和中文注释的个人理解 import socket, select, Queueserver=('192.168.2.100',10086)#创建TC ...

最新文章

  1. C++ STL之vector常用指令
  2. 数据结构--二叉树的创建和相关操作
  3. 【OpenCV3】级联分类器训练——traincascade快速使用详解
  4. 一文解决new/delete与malloc/free相关问题:区别?注意事项?使用方式?
  5. Git commit -m与-am
  6. npm 打包vue,错误 errno 126 / 清空node_modules目录
  7. css初始化_利用CSS变量实现炫酷的悬浮效果
  8. 吴恩达deeplearning.ai新课上线:TensorFlow移动和web端机器学习
  9. C++菱形继承逆向分析
  10. php中文分词类 关键词提取,php如何使用PHPAnalysis提取关键字中文分词
  11. Focal Loss-RetinaNet算法解析
  12. mt3dgis 视频教程
  13. Lync 2013正式版评估及2013版独立客户端下载
  14. 二维数组与指针(详解)
  15. 数据库备份软件带邮件发送
  16. 6s的充电电流怎么测试软件,用数字万用表测量手机充电器的充电电流的方法和问题...
  17. pdf 旋转视图,为啥不能保存?
  18. 手机签到应用的设计与手机定位方法浅析
  19. java图片叠加_[原创]JAVA中图片上叠加文字的方法
  20. myanmar android2,Myanmar Thingyan Songs 2

热门文章

  1. 数据采集程序-----直播间
  2. postman接口批量测试
  3. matplotlib函数库使用imshow绘制像素图片
  4. 节拍器在学习音乐过程中起到什么作用?-小星星节拍器怎么样?
  5. 挚爱家乡五常大米的味道
  6. 微信小程序点击查看大图
  7. 【Kibana】索引生命周期策略错误illegal_argument_exception: index.lifecycle.rollover_alias does not point to index
  8. GPU图形处理器与CPU区别
  9. CSS-浏览器缩放使边框大小改变,导致布局改变的问题
  10. echarts:饼图标签formatter的使用/饼图自定义标签