Linux: Discuss the difference between the big and small ends of the network byte order--------

Source: Internet
Author: User

Transformation of the data storage precedence order

The computer data store has two byte precedence: The high byte takes precedence (called the big-endian mode) and the low-order byte precedence (known as the small-end mode). The low address of memory stores the low byte of the data, and the high address stores the data in a high-byte manner called the small-end mode. The high address of the memory stores the low bytes of data, and the low address stores the data in a high-byte manner called the big-endian mode.

Eg: for the number of 0x12345678 in memory (note that for data, here 12 is high byte, 78 is low byte; for address, the left is the low address, the right side is the high address)

If it is stored in big-endian mode, its true number is: 0x12345678

If it is stored in a small-end mode, its true number is: 0x78563412

Comprehensive: small-end mode, the first low-byte, big-endian mode first save high bytes.

If the byte order used by a system is called the host byte order, it may be a small-ended or big-endian mode. Usually our computer stores data in small-end mode. While the port number and IP address are stored in the network byte order, not the host byte order, the network byte order is the big-endian mode. To match the host byte order and the network byte order with each other, we need to convert each of the two byte storage priorities.

Pra1 original question

The implementation converts the IP address (dotted decimal number) stored as a string into a 32-bit binary value of the host's byte order. IP is: "180.97.33.107". Hex is b4.61.21.6b

Ideas

In general, our host byte order is the small-endian byte order, that is, the selection of low-byte data storage.

1. Remove each number in the string

2. Shift Left (note that the left shift is bound to be 0)

180:00 xx B4 left shift 0-digit XX b4
97:00 00 00 61 Shift Left 8 bits 00 00 61 00
33:00 00 00 21 Shift left 16 bits 00 21 00 00
107:00 6b shift left 24 Bits 6b 00 00 00

3. OR operation

Code
#include <stdio.h> #include <stdlib.h> #include <string.h> #define IP "180.97.33.107"/* The IP address is converted to the binary value of the host byte order, and the output is represented by a 16 binary */static int My_atoh (char *ip) {    int arr[4];/* for holding 4 integers deducted from the IP address */    int my_ip;    SSCANF (IP, "%d.%d.%d.%d", arr,arr+1,arr+2,arr+3);    My_ip = (Arr[3] << 24) | (Arr[2] << 16) | (Arr[1] << 8) | ARR[0];    return my_ip;} int main (int argc, char *argv[]) {    int my_host = My_atoh (IP);    printf ("IP  :%s \ n", IP);    printf ("Host:%x \ n", my_host);    return 0;}

The results of the operation are as follows:

[Email protected] 0827]$ Gcc-o main my_atoh.c-wall[[email protected] 0827]$./mainip  : 180.97.33.107HOST:6B2161B4 [Email protected] 0827]$
Attention

A note that has nothing to do with the subject, when all scanf functions are formatted and read in, if you encounter%s, you will add ' \ o '.

Pra2 original question

The implementation converts the host byte-order (small-end mode) into a network byte order (in big-endian mode storage). That is, the host byte order is 6b2161b4–> b461216b

Idea 1

Swap the 6b with B4, 21 and 61.

Code
#include <stdio.h>int my_hton (int ip) {/    * &ip points to an integer IP with 32 bits, converts a pointer of the int* type to a pointer of type char*,     * PTR points to integers with 8 bits (第0-7位),     * ptr+1 points to integers with 8 bit representation (第8-15位),     * ptr+2 points to integers with 8 bits (第16-23位),     * ptr+ 3 points to the integer number that represents (第24-31位) with 8 bits. */    
    char *ptr = (char*) & IP;        char tmp;    TMP = ptr[0];    Ptr[0] = ptr[3];    PTR[3] = tmp;    TMP = ptr[1];    PTR[1] = ptr[2];    PTR[2] = tmp;    return IP;} int main (int argc, char *argv[]) {    int my_host = 0X6B2161B4;    int my_net = My_hton (my_host);    printf ("My_host:%x \ n", my_host);    printf ("My_net:%x \ n", my_net);    return 0;}

The results of the operation are as follows:

[Email protected] 0827]$ Gcc-o main my_hton.c-wall[[email protected] 0827]$./mainmy_host:6b2161b4my_net:b461216b
Attention

In fact, the IP address is dotted decimal, with each byte representing a range of 0-255. Our char type usually defaults to a signed number, meaning that it represents a range of-128-127. So is the part that I marked yellow in the code wrong? In fact, there is no mistake, because here we are only concerned about the storage of each bit of IP, does not require the actual decimal value of each byte. When formatted with printf, the output is formatted according to the binary form of the data in memory, and the 16 binary form is not negative.

Idea 2

1. For 0X6B2161B4, first move right and proceed with operation, take out each byte

For example: To remove 6b, then 0x6b2161b4 to the right 24 bits, and then with the 0xFF operation can

Note: You must not proceed with the operation first, and then move right. For example, to remove 6b, first make 0X6B2161B4 and 0xff000000 with operation, then move right 24 bits. This is wrong because the right shift will complement the sign bit. (Tips: Shift left 0 and discard symbol bits)

2. Move left again and adjust to the appropriate position. (The following two steps are similar to PRA1)

3. OR operation

Code
#include <stdio.h>int my_hton2 (int ip) {    int my_net;    My_net = ((ip&0xff) <<24) | (((ip>>8) &0xff) << 16) | (((ip>>16) &0xff) << 8) | ((ip>>24) &0xff);    return my_net;} int main (int argc, char *argv[]) {    int my_host = 0X6B2161B4;    int my_net = My_hton2 (my_host);    printf ("My_host:%x \ n", my_host);    printf ("My_net:%x \ n", my_net);    return 0;}
Pra3 original question

Implementation converts network byte order to dotted decimal

Code
#include <stdio.h>static char* my_ntoa (int ip) {    static char buf[1024] = "";    sprintf (buf, "%d.%d.%d.%d", (IP >>) & 0xff, (IP >> +) & 0xff, (IP >> 8) & 0xFF, IP & 0x FF);    return BUF;} int main (int argc,char *argv[]) {    int my_net = 0xb461216b;    printf ("My_net:%x \ n", my_net);    printf ("IP    :%s \ n", My_ntoa (my_net));    return 0;}

Linux: Discuss the difference between the big and small ends of the network byte order--------

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.