>
id="f" width="120px" height="240px" src="" frameborder="no" border="0" marginwidth="0" marginheight="0" allowtransparency="yes" scrolling="no" style="margin: 0px; padding: 0px;">
收藏到qq書籤
分享至微博
最近在嘗試與c互動的時候又用上了這玩意,所以不得不再看看。其實就是c要求我一定要有包頭。。。其實純字串也不錯嘛。幹嘛非得搞個包頭呢?真糾結 .。
手冊上有pack與unpack的介紹,但都是英文的。。。
任何一款擁有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 要求的多,那麼多餘的引數被忽略。
下面還是用例子來說明用法會容易理解一點:
php**
關於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
);
學習資料:
我上面的內容來自於:我現在已經順利的使用完了。黑黑
php pack 函式詳解與示例
pack和unpack在一般的程式中還真的不容易見到,但是如果你用過很久以前的php生成excel你就會知道了。他的excel的頭就是pack出來的 最近在嘗試與c互動的時候又用上了這玩意,所以不得不再看看。其實就是c要求我一定要有包頭。其實純字串也不錯嘛。幹嘛非得搞個包頭呢?真糾結 手冊上有pac...
PHP pack函式選項列表
pack 壓縮資料到位字串之中。語法 string pack string format,mixed args 返回值 字串 a將字串空白以 null 字元填滿 a將字串空白以 space 字元 空格 填滿 h十六進製字串,低位在前 h十六進製字串,高位在前 c有號字元 c無號字元 s有號短整數 十...
SQL 函式 TRUNCATE詳解示例
truncate x,d x 表示需要處理的數字,d 表示需要擷取的位數。如果 d 為零,則返回的數字不含小數。d 也可以是負數,這樣會把整數的部分置零。示例如下 mysql select truncate 1.223,1 1.2mysql select truncate 1.999,1 1.9my...