php 字节序,php字节序转换的方法

php字节序转换的方法:1、使用“htons”方法把unsigned short类型从主机序转换到网络序;2、使用“htonl”把“unsigned long”类型从主机序转换到网络序等。

a08a69c48a747cebd10f9bd80c49b75d.png

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);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值