php位元組序轉換的方法

藏色散人
發布: 2023-03-04 20:02:02
原創
3618 人瀏覽過

php位元組序列轉換的方法:1.使用「htons」方法把unsigned short類型從主機序列轉換到網路序列;2、使用「htonl」把「unsigned long」類型從主機序列轉換到網路序等。

php位元組序轉換的方法

推薦:《PHP影片教學

php主機位元組序與網路位元組序

使用php寫socket程式時,也需要注意主機字節序和網路字節序的轉換

主機字節序就是我們平常說的大端和小端模式:不同的CPU 有不同的位元組序類型,這些位元組序是指整數在記憶體中保存的順序這個叫做主機序號。 Big-Endian和Little-Endian。引用標準的Big-Endian和Little-Endian的定義如下:

  a) Little-Endian就是低位元組排放在記憶體的低位址端,高位元組排放在記憶體的高位址端。

  b) Big-Endian就是高位元組排放在記憶體的低位址端,低位元組排放在記憶體的高位址端。

範例:在記憶體中雙字0x01020304(DWORD)的儲存方式

内存地址
4000 4001 4002 4003
LE 04 03 02 01
BE 01 02 03 04
登入後複製

網路位元組順序是指TCP/IP中規定好的一種資料表示格式,它與具體的CPU類型、作業系統等無關,因此可以保證資料在不同主機之間傳輸時能夠正確解釋。網路位元組順序採用big endian排序方式。位元組序,顧名思義位元的順序,就是大於一個位元組類型的資料在記憶體中的存放順序,一個位元組的資料沒有順序的問題了。

為了進行轉換bsd socket 提供了轉換的函數有下面四個

  htons 把unsigned short 類型從主機序列轉換到網絡序列

#  htonl 把unsigned long 類型從主機序列轉換到網路序列

  ntohs 把unsigned short 類型從網路序列轉換到主機序列

  ntohl 把unsigned long 型別從網路序列轉換到主機序列

   把使用於使用little endian 的系統中這些函數會把字節序進行轉換

  在使用big endian 類型的系統中這些函數會定義成空宏

注意:

##  1 、網路與主機位元組轉換函數:htons ntohs htonl ntohl (s 就是short l 是long h 是host n 是network)

  2 、不同的CPU 上運作不同的作業系統,位元組序也是不同的

在網頁程式開發時或是跨平台開發時也應該注意保證只用一種字節序不然兩方的解釋不一樣就會產生bug.

PHP中並沒提供htons,htonl功能的函數,在進行網路通訊時,可以透過

string pack ( string $format [, mixed $args [, mixed $... ]] )
array unpack ( string $format , string $data )
登入後複製

進行編解碼

其中,format 可以取下面的值:

Code     Description
a     NUL-padded string
A     SPACE-padded string
h     Hex string, low nibble first
H     Hex string, high nibble first
c     signed char
C     unsigned char
s     signed short (always 16 bit, machine byte order)
S     unsigned short (always 16 bit, machine byte order)
n     unsigned short (always 16 bit, big endian byte order)
v     unsigned short (always 16 bit, little endian byte order)
i     signed integer (machine dependent size and byte order)
I     unsigned integer (machine dependent size and byte order)
l     signed long (always 32 bit, machine byte order)
L     unsigned long (always 32 bit, machine byte order)
N     unsigned long (always 32 bit, big endian byte order)
V     unsigned long (always 32 bit, little endian byte order)
f     float (machine dependent size and representation)
d     double (machine dependent size and representation)
x     NUL byte
X     Back up one byte
Z     NUL-padded string (new in PHP 5.5)
@     NUL-fill to absolute position
登入後複製

網絡通訊

例如現在要透過PHP發送封包到伺服器來登入。在只需要提供使用者名稱(最多30個位元組)和密碼(md5之後固定為32位元組)的情況下,可以建構如下資料包(當然這事先需要跟伺服器協商好資料包的規範,本例以網路字節序通訊):

套件結構:

字段  字节数 说明
包头  定长         每一个通信消息必须包含的内容
包体  不定长 根据每个通信消息的不同产生变化
登入後複製

其中包頭詳細內容如下:

字段               字节数 类型       说明
pkg_len         2     ushort     整个包的长度,不超过4K
version         1     uchar     通讯协议版本号
command_id 2     ushort     消息命令ID
result         2     short     请求时不起作用;请求返回时使用
登入後複製

當然實際中可能會涉及到各種校驗。本文為了簡單,只是列舉一下通常的工作流程及處理的方式。

登入(執行命儲1001)

字段       字节数 类型         说明
用户名 30     uchar[30] 登录用户名
密码         32     uchar[32] 登录密码
登入後複製

包頭是定長的,透過計算可知包頭佔7個字節,並且包頭在包體之前。例如用戶陳一回需要登錄,密碼是123456,程式碼如下:

<?php
$version    = 1;
$result     = 0;
$command_id = 1001;
$username   = "陈一回";
$password   = md5("123456");
// 构造包体
$bin_body   = pack("a30a32", $username, $password);
// 包体长度
$body_len   = strlen($bin_body);
$bin_head   = pack("nCns", $body_len, $version, $command_id, $result); //result为什么使用了主机字节序
$bin_data   = $bin_head . $bin_body;
// 发送数据
// socket_write($socket, $bin_data, strlen($bin_data));
// socket_close($socket);
登入後複製

以上是php位元組序轉換的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板