>  기사  >  백엔드 개발  >  PHP 바이트 순서 변환 방법

PHP 바이트 순서 변환 방법

藏色散人
藏色散人원래의
2020-08-20 09:58:523630검색

PHP 바이트 순서 변환 방법: 1. "htons" 방법을 사용하여 부호 없는 짧은 유형을 호스트 순서에서 네트워크 순서로 변환합니다. 2. "htonl"을 사용하여 "부호 없는 긴" 유형을 호스트 순서에서 네트워크 순서로 변환합니다. 등.

PHP 바이트 순서 변환 방법

추천: "PHP 비디오 튜토리얼"

php 호스트 바이트 순서 및 네트워크 바이트 순서

PHP를 사용하여 소켓 프로그램을 작성할 때 호스트 바이트 순서 및 네트워크에도 주의해야 합니다. 바이트 순서 변환

호스트 바이트 순서는 우리가 일반적으로 빅 엔디안 및 리틀 엔디안 모드라고 부르는 것입니다. CPU마다 바이트 순서 유형이 다릅니다. 이러한 바이트 순서는 정수가 메모리에 저장되는 순서를 나타냅니다. 빅엔디안과 리틀엔디안. 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 유형, 운영 체제 등과는 아무런 관련이 없습니다. 이렇게 하면 서로 다른 호스트 간에 데이터가 전송될 때 데이터가 올바르게 해석될 수 있습니다. 네트워크 바이트 순서는 빅 엔디안 정렬을 사용합니다. 바이트 순서는 이름에서 알 수 있듯이 1바이트보다 큰 데이터가 메모리에 저장되는 순서입니다. 1바이트의 데이터에는 순서 문제가 없습니다.

bsd 소켓을 변환하기 위해 다음 네 가지 변환 함수를 제공합니다.

htons는 호스트 시퀀스의 부호 없는 짧은 유형을 네트워크 시퀀스로 변환합니다.

htonl은 부호 없는 긴 유형을 호스트 시퀀스에서 네트워크 시퀀스로 변환합니다.

ntohs는 변환합니다. unsigned short 유형을 네트워크 순서에서 호스트 순서로 변환

 ntohl unsigned long 유형을 네트워크 순서에서 호스트 순서로 변환

little endian을 사용하는 시스템에서 이 함수는 바이트 순서를 변환합니다.

big endian 유형을 사용하는 시스템에서 이러한 함수는 빈 매크로로 정의됩니다

참고:

 1. 네트워크 및 호스트 바이트 변환 기능: htons ntohs htonl ntohl(s는 짧음 l은 길다 h는 호스트 n은 네트워크)

 2. 다른 CPU에서 실행 다른 운영 체제는 다른 바이트 순서. 네트워크 프로그램을 개발하거나 크로스 플랫폼 개발을 할 때는 반드시 하나의 바이트 순서만 사용하도록 주의해야 합니다. 그렇지 않으면 두 당사자가 다르게 해석하면 버그가 발생할 수 있습니다.

PHP에는 기능이 없습니다. 및 htonl 기능을 사용하면

string pack ( string $format [, mixed $args [, mixed $... ]] )
array unpack ( string $format , string $data )

를 통해 인코딩 및 디코딩할 수 있습니다. 그 중 형식은 다음 값을 사용할 수 있습니다.

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바이트를 차지하고 패키지 본문 앞에 있는 것을 알 수 있습니다. 예를 들어 사용자 Chen Yihui는 로그인해야 하며 비밀번호는 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.