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
/************************************************************************* > File name:my_atoh.c > Author: Krischou > Mail:[email protected] > Created time:wed 08:52:38 PM CST *************************** *********************************************/#include<stdio.h>#include<stdlib.h>#include<string.h>#defineIP "180.97.33.107"/*converts the IP address to the binary value of the host byte order, and the output is represented by a 16 binary*/Static intMy_atoh (Char*IP) { intarr[4];/*for storing 4 integers that are deducted from the IP address*/ intmy_ip; SSCANF (IP,"%d.%d.%d.%d", arr,arr+1, arr+2, arr+3); My_ip= (arr[3] << -) | (arr[2] << -) | (arr[1] <<8) | arr[0]; returnmy_ip;}intMainintargcChar*argv[]) { intMy_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:
0827] $ gcc-o Main my_atoh.c-0827]$./mainip 180.97. 33.1070827]$
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
/* ************************************************************************ > File name:my_hton.c > Author:krischou > Mail:[email protected] > Created time:wed 09:26:13 PM CST ************* */<stdio.h>int My_hton (int IP) { /* &ip points to an integer IP of 32 bits, converting a pointer of type int* to a pointer of type char*. * The PTR points to integers with 8 bits (第0-7位), * ptr+1 points to integers with 8 bits (第8-15位), * ptr+2 points to integers with 8 bits (第16-23位), * ptr+3 points to the integer number represented by 8 bits (第24-31位). */
Char*ptr = (Char*) &IP; Chartmp; TMP= ptr[0]; ptr[0] = ptr[3]; ptr[3] =tmp; TMP= ptr[1]; ptr[1] = ptr[2]; ptr[2] =tmp; returnIP;}intMainintargcChar*argv[]) { intMy_host =0x6b2161b4; intMy_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:
0827] $ gcc-o Main MY_HTON.C-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
/************************************************************************* > File name:my_hton2.c > Author: Krischou > Mail:[email protected] > Created time:wed 10:08:07 PM CST ************************** **********************************************/#include<stdio.h>intMy_hton2 (intIP) { intmy_net; My_net= ((ip&0xFF) << -) | (((ip>>8) &0xFF) << -) | (((ip>> -) &0xFF) <<8) | ((ip>> -) &0xFF); returnmy_net;}intMainintargcChar*argv[]) { intMy_host =0x6b2161b4; intMy_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
/************************************************************************* > File name:my_ntoa.c > Author: Krischou > Mail:[email protected] > Created time:wed 10:27:03 PM CST *************************** *********************************************/#include<stdio.h>Static Char* MY_NTOA (intIP) { Static Charbuf[1024x768] =""; sprintf (BUF,"%d.%d.%d.%d", (IP >> -) &0xFF, (IP >> -) &0xFF, (IP >>8) &0xFF, IP &0xFF); returnbuf;}intMainintargcChar*argv[]) { intMy_net =0xb461216b; printf ("my_net:%x \ n", my_net); printf ("IP:%s \ n", My_ntoa (my_net)); return 0;}
Linux network programming, small end mode and big-endian mode