php字节序转换的案例
这篇文章主要介绍了php字节序转换的案例,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。
php字节序转换的方法:1、使用“htons”方法把unsigned short类型从主机序转换到网络序;2、使用“htonl”把“unsigned long”类型从主机序转换到网络序等。
php主机字节序和网络字节序
使用php编写socket程序时,也需要注意主机字节序和网络字节序的转换
主机字节序就是我们平常说的大端和小端模式:不同的 CPU 有不同的字节序类型,这些字节序是指整数在内存中保存的顺序 这个叫做主机序。Big-Endian和Little-Endian。引用标准的Big-Endian和Little-Endian的定义如下:
a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
例子:在内存中双字0x01020304(DWORD)的存储方式
内存地址4000 4001 4002 4003LE 04 03 02 01BE 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 Descriptiona NUL-padded stringA SPACE-padded stringh Hex string, low nibble firstH Hex string, high nibble firstc signed charC unsigned chars 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 byteX Back up one byteZ NUL-padded string (new in PHP 5.5)@ NUL-fill to absolute position
网络通信
比如现在要通过PHP发送数据包到服务器来登录。在仅需要提供用户名(最多30个字节)和密码(md5之后固定为32字节)的情况下,可以构造如下数据包(当然这事先需要跟服务器协商好数据包的规范,本例以网络字节序通信):
包结构:
字段 字节数 说明包头 定长 每一个通信消息必须包含的内容包体 不定长 根据每个通信消息的不同产生变化
其中包头详细内容如下:
字段 字节数 类型 说明pkg_len 2 ushort 整个包的长度,不超过4Kversion 1 uchar 通讯协议版本号command_id 2 ushort 消息命令IDresult 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字节序转换的案例内容对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,遇到问题就找亿速云,详细的解决方法等着你来学习!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。