Même résultat pour htonl() et ntohl() sur un entier
J'ai couru le programme suivant sur little-endian [LE] machine [Linux, processeur Intel]. Je suis incapable d'expliquer le 3 sorties dans l'extrait de code ci-dessous. Depuis que la machine est à CHIER, la valeur de a
est stockée en tant que 0x78563412
. Lors de l'impression, c'est l'affichage de sa valeur réelle. Depuis sa une LE machine, j'attends ntohl()
d'être un no-op et d'affichage 0x78563412
, qu'il est en train de faire. Toutefois, je m'attends à 0x12345678
pour la 2ème instruction d'impression contenant htonl()
. Quelqu'un peut-il m'aider à comprendre pourquoi ils sont même?
int main()
{
int a = 0x12345678;
printf("Original - 0x%x\n", (a));
printf("Network - 0x%x\n", htonl(a));
printf("Host - 0x%x\n", ntohl(a));
return 0;
}
De sortie:
Original - 0x12345678
Network - 0x78563412
Host - 0x78563412
OriginalL'auteur Bhaskar | 2012-07-10
Vous devez vous connecter pour publier un commentaire.
C'est l'erreur. Ordre des octets de réseau est big-endian, l'ordre des octets de l'hôte est en little-endian. Par conséquent, les deux
ntohl
ethtonl
retour d'un octet échangé version de leur entrée.Rappelez-vous, le point de
htonl
est que vous pouvez prendre un entier sur l'ordinateur hôte, puis d'écrire:et le résultat est que la mémoire de
i
, lorsqu'ils sont interprétés à l'aide de network byte order, a la même valeur quea
. Donc, si vous écrivez à la représentation d'objet dei
à une prise secteur et le lecteur à l'autre extrémité attend un entier de 4 octets dans l'ordre des octets de réseau, il va lire la valeur dea
.Est-ce que vous l'intention d'écrire? Si
ntohl
ont été un no-op (ou plutôt, une identité de fonction), puis de troisième ligne nécessairement serait d'imprimer la même chose que votre première ligne, parce que vous auriezntohl(a) == a
. C'est ce qui se passe sur big-endian implémentations, où votre programme imprime:x == htonl(ntohl(x))
. Mais ce n'est pas le cas et votre explication a été très utile.Brian Roach point est important, alors: vous n'avez jamais calculé
htonl(ntohl(a))
. Vous avez calculéhtonl(a)
etntohl(a)
.merci beaucoup! Grande explication
démo pour big-endian machines. En comparaison avec les little-endian version sur la même architecture, il peut être vu que pas de byte swap besoin d'instructions
OriginalL'auteur Steve Jessop
htonl
etntohl
sont exactement les mêmes fonctions. Ils sont censés satisfairehtonl(ntohl(x)) == x
. Ils sont nommés différemment seulement pour la documentation (vous rendre explicite le fait que la conversion à partir d'hôte-réseau ou dans l'autre sens, même si c'est la même chose). Donc, sur un little-endian machine, ils exercent octet-échange, et sur un big-endian machine, ils sont à la fois non-ops.4321
), ni little-endian (commandé1234
), mais ordonné par exemple3214
, vous auriez encorehtonl(ntohl(x))
, maishtonl
etntohl
ne ferait pas la même chose, ils seraient de 8 bits en rotation dans des directions opposées. J'espère qu'il n'en architecture existe, mais il pourrait mettre en œuvre l'API sockets grâce au fait quehtonl
etntohl
sont des fonctions distinctes.vous avez raison, bien sûr. C'est probablement le réel raison pour laquelle nous avons deux fonctions différentes. en.wikipedia.org/wiki/Endianness#Middle-endian
Ouais, j'ai juste pensé que c'était d'essayer de supprimer mon commentaire, mais vous êtes rapide! :-).
Aimer le nom de "stupide-endian". 🙂
Je pensais que c'était appelée VAX-endian?
OriginalL'auteur Alok Singhal
Parce que vous êtes de passage
a
par valeur et par conséquent, il n'est pas modifiée par l'une de ces fonctions.Vous avez l'impression que
htonl()
etntohl()
sont retour.Modifier pour ajouter: j'ai raté où vous pensait être un no-op. Il n'est pas. Les deux vont faire exactement la même chose sur un CHIER de la machine; inverser l'ordre des octets.
ntohl()
attend de vous pour être en passant un réseau ordonné par octetint
OriginalL'auteur Brian Roach
Dans votre programme quand vous écrivez
int a;
vous sais quea
contient un hôte commandé entier, le programme ne le sais pas. On peut facilement fournir un int contenant déjà une valeur en réseau de commande. Bien sûr, si vous utilisez un opérateur arithmétique sur une valeur qui n'est pas dans l'hôte de l'ordre, le résultat sera faux à partir d'un réseau de point de vue du réseau si l'ordre n'est pas le même que l'hôte de l'ordre.Mais ce n'est pas si farfelu, le réseau ordonné de valeurs sont souvent gardés exactement de cette manière dans le faible niveau des structures, avant d'être envoyé ou juste après avoir été reçu.
Quel est le problème avec votre programme, c'est que lorsque vous appelez
ntohl()
votre sont prometteurs pour lantohl()
fonction de laint
que vous fournissez est la valeur stockée en mémoire dans le réseau de commande. C'est le contrat. Si ce n'est pas vrai, la fonction de ne pas accomplir ce que vous attendez, et c'est ce que vous seing.Que les autres, a expliqué sur la plupart des systèmes (gros ou petit, mais pas stupide-endians) les deux fonctions sont généralement identiques, soit un octets inverse ou un no-op.
OriginalL'auteur kriss