Maison  >  Article  >  développement back-end  >  Méthode de conversion de l'ordre des octets PHP

Méthode de conversion de l'ordre des octets PHP

藏色散人
藏色散人original
2020-08-20 09:58:523554parcourir

Méthode de conversion de l'ordre des octets PHP : 1. Utilisez la méthode "htons" pour convertir le type court non signé de l'ordre de l'hôte en ordre du réseau ; 2. Utilisez "htonl" pour convertir le type "long non signé" de l'ordre de l'hôte ; à l'ordre du réseau, etc.

Méthode de conversion de l'ordre des octets PHP

Recommandé : "Tutoriel vidéo PHP"

Ordre des octets de l'hôte PHP et ordre des octets du réseau

Lorsque vous utilisez PHP pour écrire un programme socket, vous devez également faire attention à la conversion entre l'ordre des octets de l'hôte et l'ordre des octets du réseau

L'ordre des octets de l'hôte est ce que nous appelons habituellement big endian et Mode Little Endian : différents processeurs ont différents types d'endianité. Ces endianités font référence à l'ordre dans lequel les entiers sont stockés en mémoire. C'est ce qu'on appelle l'ordre des hôtes. Big-Endian et Little-Endian. Les définitions standards de Big-Endian et Little-Endian sont citées comme suit :

a) Little-Endian signifie que les octets de poids faible sont disposés à l'extrémité de l'adresse basse de la mémoire, et l'octet de poids fort les octets sont disposés à l’extrémité haute de la mémoire.

b) Big-Endian signifie que les octets de poids fort sont disposés à l'extrémité de l'adresse basse de la mémoire et que les octets de poids faible sont disposés à l'extrémité de l'adresse haute de la mémoire.

Exemple : La méthode de stockage du double mot 0x01020304 (DWORD) en mémoire

内存地址
4000 4001 4002 4003
LE 04 03 02 01
BE 01 02 03 04

L'ordre des octets du réseau fait référence à un format de représentation des données spécifié dans TCP/IP, qui est lié au spécifique qu'il a rien à voir avec le type de CPU, le système d'exploitation, etc., garantissant ainsi que les données peuvent être interprétées correctement lorsqu'elles sont transmises entre différents hôtes. L’ordre des octets du réseau utilise le tri big endian. L'ordre des octets, comme son nom l'indique, est l'ordre dans lequel les données de plus d'un octet sont stockées en mémoire. Il n'y a pas de problème d'ordre avec les données d'un octet.

Afin de convertir, le socket bsd fournit les quatre fonctions de conversion suivantes

htons convertit le type court non signé de la séquence hôte en séquence réseau

htonl convertit le type long non signé de Convert ordre d'hôte en ordre réseau

ntohs Convertir le type court non signé de l'ordre réseau en ordre hôte

ntohl Convertir le type long non signé de l'ordre réseau en ordre hôte

Lors de l'utilisation de In Little Endian systèmes, ces fonctions convertiront l'ordre des octets

 ; dans les systèmes big endian, ces fonctions seront définies comme des macros vides

Remarque :

1, conversion d'octets réseau et hôte fonction : htons ntohs htonl ntohl (s est court l est long h est l'hôte n est le réseau)

 2. Différents systèmes d'exploitation fonctionnent sur différents processeurs et l'ordre des octets est également différent

. Lors du développement de programmes réseau ou de développement multiplateforme, vous devez également veiller à ce qu'un seul ordre d'octet soit utilisé, sinon des interprétations différentes par les deux parties provoqueront des bugs.

Fonctions de fusion PHP qui ne fournissent pas de htons et les fonctions htonl peuvent être codées et décodées via

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

pendant la communication réseau

Parmi elles, le format peut prendre les valeurs suivantes :

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

Communication réseau

Par exemple, vous devez maintenant envoyer un paquet de données au serveur via PHP pour vous connecter. Lorsque vous devez uniquement fournir le nom d'utilisateur (jusqu'à 30 octets) et le mot de passe (fixé à 32 octets après md5), vous pouvez construire le paquet de données suivant (bien sûr, cela nécessite de négocier les spécifications du paquet de données avec le serveur au préalable . Dans cet exemple de communication par ordre d'octets du réseau) :

Structure du paquet :

字段  字节数 说明
包头  定长         每一个通信消息必须包含的内容
包体  不定长 根据每个通信消息的不同产生变化

Les détails de l'en-tête sont les suivants :

字段               字节数 类型       说明
pkg_len         2     ushort     整个包的长度,不超过4K
version         1     uchar     通讯协议版本号
command_id 2     ushort     消息命令ID
result         2     short     请求时不起作用;请求返回时使用

Bien sûr, diverses vérifications peuvent être impliquées. en pratique. Par souci de simplicité, cet article répertorie uniquement les flux de travail et les méthodes de traitement courants.

Connexion (exécuter la commande 1001)

字段       字节数 类型         说明
用户名 30     uchar[30] 登录用户名
密码         32     uchar[32] 登录密码

L'en-tête est de longueur fixe. Grâce au calcul, on peut voir que l'en-tête occupe 7 octets et que l'en-tête est avant le corps du paquet. Par exemple, l'utilisateur Chen Yihui doit se connecter et le mot de passe est 123456, le code est le suivant :

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn