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);
转自:http://www.kongqingquan.com/archives/24
参考:http://www.cnblogs.com/andydao/p/4200662.html
php主机字节序和网络字节序相关推荐
- linux网络编程一:主机字节序与网络字节序的的判断
linux网络编程一:主机字节序与网络字节序的的判断(1)现代CPU的累加器一次能装载至少4字节(32位),即一个整数.那么这4字节在内存中排列的顺序将影响它被累加器装载成的整数值,这就是字节序问题 ...
- 主机字节序与网络字节序的转换函数:htonl、ntohl、htons、ntohs
Part 1: htons函数具体解释 在Linux和Windows网络编程时需要用到htons和htonl函数,用来将主机字节顺序转换为网络字节顺序. 在Intel机器下,执行以下程序 i ...
- 【Linux】主机字节序和网络字节序
(一)问题提出:为什么要有主机字节序和网络字节序的存在? 现在大多数PC机器都是小端字节序(小端存储),也称为主机字节序:但不排除有大端PC机器的存在. 若在两台字节序不同的主机上传输数据时,接收端将 ...
- 主机字节序与网络字节序的转换函数:htonl、ntohl、htons、ntohs【转】
(转自:https://blog.csdn.net/kulala082/article/details/53431473) Part 1: htons函数具体解释 在Linux和Windows网络编程 ...
- 字节序 主机字节序与网络字节序互相转换
目录 1.什么是字节序? 2.字节序分类 3.为什么要有大端字节序和小端字节序? 4.主机字节序和网络字节序 5.主机字节序与网络字节序的转换 6.怎么判断自己的主机是小端字节序还是大端字节序呢? 7 ...
- 主机字节序和网络字节序
1.大端字节序和小端字节序: 大端字节序存储时值的高位存储在较小的地址,值的低位存储在较大的地址. 小端字节序存储时值的高位存储在较大的地址,值的低位存储在较小的地址. 以0x12345678为例: ...
- Linux---主机字节序与网络字节序
现在的CPU累加器一次能够装载至少4个字节的一个整数,那么字节在内存中的排列顺序不同,导致累加器使用的结果不同,这就是字节序问题 . 例如: 我们存储一个int类型的数字:int a = 1; 主机字 ...
- 什么是字节序(端序、低端字节序、高端字节序、网络字节序)
前言 一个内容为12(字符串)的文本文件,它的第一个字节是什么(小端序)?如果你的回答是0x32,那你真的应该好好理解下字节序了.如下图所示,我这里的正确答案是0x31.当然如果你的回答是不一定,这似 ...
- 本地字节序和网络字节序
本地字节序和网络字节序 字节序指不同的CPU访问内存中多字节数据的时候,存在大小端的问题,并且一定是访问多字节数据的时候才会存在大小端的问题,如果CPU访问的是字符串,则不存在大小端的问题: 那么如何 ...
- 本地字节序与网络字节序的相互转换(IP地址、端口号)
一般数据在内存中是按照字节存储的,存储的方式分为大端和小端.在不知道对方主机的存储方式的情况下,我们不知道是否需要转换数据的存储方式.因此,TCP/IP协议规定:发送到网络的数据流应采用大端字节序! ...
最新文章
- SpringMVC底层数据传输校验的方案(修改版)
- php数据关系图,如何利用navicat查看数据表的ER关系图
- 限制文本输入框只能输入0-9数字
- 为什么别的手机都能接收wifi,而红米手机却收不到?
- VIM 快捷键汇总(持续更新)
- Java - 批量生成二维码压缩包
- 在Mac电脑上:更改移动硬盘的格式
- strlen函数原理
- 创建主键报错:Incorrect column specifier for column ‘id‘
- 嵌入式:Altium Designer18提升速度的操作(画开发板笔记)
- 计算机图形学原理及实践学习笔记第一章
- 中缀表达式转后缀表达式两位数_什么是圆形磁动势?永磁无刷电机是怎么转起来的?...
- 通俗理解STM32 SPI通信(主从双机SPI通信)
- 2021最新整理JAVA常见面试题附答案
- word2016页码设置(包括目录去除页码)
- Kotlin 4. Kotlin 函数注解:Suppress,Volatile, Synchronized, Bindable, RequiresApi,SerializedName
- Thinkpad 笔记本散热风扇声音大解决办法
- Windows远程连接电脑怎么配置远程音频
- python定义字符串变量有两种常用方式_Python 1基础语法二(标识符、关键字、变量和字符串)...
- Pixar's USD format for windows--安装和使用演示
热门文章
- 机器学习中的数学——优化技术:参数初始化策略
- 计算机室英语单词怎么读,“计算机”英语单词怎么读?
- 【解决方案】微信公众号文章加载很慢,图片加载不出来,或者weixin.qq.com这个域名都加载不出来
- java代码实现流程中的会签_Activiti实现会签功能
- Activiti7工作流引擎:进阶篇(八) 会签
- UvaLA 4670 Dominating Patterns
- C#实战之CAD二次开发002:绘制直线和绘制圆
- unixbench测试CPU性能工具/mbw测试内存
- 遗传算法之:八皇后问题
- 无线路由器DNS服务器异常,fast无线路由器dns异常的解决方法