您好,登錄后才能下訂單哦!
這篇文章主要介紹了php字節(jié)序轉(zhuǎn)換的案例,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
php字節(jié)序轉(zhuǎn)換的方法:1、使用“htons”方法把unsigned short類型從主機序轉(zhuǎn)換到網(wǎng)絡(luò)序;2、使用“htonl”把“unsigned long”類型從主機序轉(zhuǎn)換到網(wǎng)絡(luò)序等。
php主機字節(jié)序和網(wǎng)絡(luò)字節(jié)序
使用php編寫socket程序時,也需要注意主機字節(jié)序和網(wǎng)絡(luò)字節(jié)序的轉(zhuǎn)換
主機字節(jié)序就是我們平常說的大端和小端模式:不同的 CPU 有不同的字節(jié)序類型,這些字節(jié)序是指整數(shù)在內(nèi)存中保存的順序 這個叫做主機序。Big-Endian和Little-Endian。引用標準的Big-Endian和Little-Endian的定義如下:
a) Little-Endian就是低位字節(jié)排放在內(nèi)存的低地址端,高位字節(jié)排放在內(nèi)存的高地址端。
b) Big-Endian就是高位字節(jié)排放在內(nèi)存的低地址端,低位字節(jié)排放在內(nèi)存的高地址端。
例子:在內(nèi)存中雙字0x01020304(DWORD)的存儲方式
內(nèi)存地址 4000 4001 4002 4003 LE 04 03 02 01 BE 01 02 03 04
網(wǎng)絡(luò)字節(jié)順序是指TCP/IP中規(guī)定好的一種數(shù)據(jù)表示格式,它與具體的CPU類型、操作系統(tǒng)等無關(guān),從而可以保證數(shù)據(jù)在不同主機之間傳輸時能夠被正確解釋。網(wǎng)絡(luò)字節(jié)順序采用big endian排序方式。字節(jié)序,顧名思義字節(jié)的順序,就是大于一個字節(jié)類型的數(shù)據(jù)在內(nèi)存中的存放順序,一個字節(jié)的數(shù)據(jù)沒有順序的問題了。
為了進行轉(zhuǎn)換 bsd socket 提供了轉(zhuǎn)換的函數(shù) 有下面四個
htons 把 unsigned short 類型從主機序轉(zhuǎn)換到網(wǎng)絡(luò)序
htonl 把 unsigned long 類型從主機序轉(zhuǎn)換到網(wǎng)絡(luò)序
ntohs 把 unsigned short 類型從網(wǎng)絡(luò)序轉(zhuǎn)換到主機序
ntohl 把 unsigned long 類型從網(wǎng)絡(luò)序轉(zhuǎn)換到主機序
在使用 little endian 的系統(tǒng)中 這些函數(shù)會把字節(jié)序進行轉(zhuǎn)換
在使用 big endian 類型的系統(tǒng)中 這些函數(shù)會定義成空宏
注意:
1 、網(wǎng)絡(luò)與主機字節(jié)轉(zhuǎn)換函數(shù) :htons ntohs htonl ntohl (s 就是 short l 是 long h 是 host n 是 network)
2 、不同的 CPU 上運行不同的操作系統(tǒng),字節(jié)序也是不同的
在網(wǎng)絡(luò)程序開發(fā)時 或是跨平臺開發(fā)時 也應該注意保證只用一種字節(jié)序 不然兩方的解釋不一樣就會產(chǎn)生bug.
PHP中并沒提供htons,htonl功能的函數(shù),在進行網(wǎng)絡(luò)通信時,可以通過
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
網(wǎng)絡(luò)通信
比如現(xiàn)在要通過PHP發(fā)送數(shù)據(jù)包到服務(wù)器來登錄。在僅需要提供用戶名(最多30個字節(jié))和密碼(md5之后固定為32字節(jié))的情況下,可以構(gòu)造如下數(shù)據(jù)包(當然這事先需要跟服務(wù)器協(xié)商好數(shù)據(jù)包的規(guī)范,本例以網(wǎng)絡(luò)字節(jié)序通信):
包結(jié)構(gòu):
字段 字節(jié)數(shù) 說明 包頭 定長 每一個通信消息必須包含的內(nèi)容 包體 不定長 根據(jù)每個通信消息的不同產(chǎn)生變化
其中包頭詳細內(nèi)容如下:
字段 字節(jié)數(shù) 類型 說明 pkg_len 2 ushort 整個包的長度,不超過4K version 1 uchar 通訊協(xié)議版本號 command_id 2 ushort 消息命令I(lǐng)D result 2 short 請求時不起作用;請求返回時使用
當然實際中可能會涉及到各種校驗。本文為了簡單,只是列舉一下通常的工作流程及處理的方式。
登錄(執(zhí)行命儲1001)
字段 字節(jié)數(shù) 類型 說明 用戶名 30 uchar[30] 登錄用戶名 密碼 32 uchar[32] 登錄密碼
包頭是定長的,通過計算可知包頭占7個字節(jié),并且包頭在包體之前。比如用戶陳一回需要登錄,密碼是123456,則代碼如下:
<?php $version = 1; $result = 0; $command_id = 1001; $username = "陳一回"; $password = md5("123456"); // 構(gòu)造包體 $bin_body = pack("a30a32", $username, $password); // 包體長度 $body_len = strlen($bin_body); $bin_head = pack("nCns", $body_len, $version, $command_id, $result); //result為什么使用了主機字節(jié)序 $bin_data = $bin_head . $bin_body; // 發(fā)送數(shù)據(jù) // socket_write($socket, $bin_data, strlen($bin_data)); // socket_close($socket);
感謝你能夠認真閱讀完這篇文章,希望小編分享php字節(jié)序轉(zhuǎn)換的案例內(nèi)容對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。