The socket portion of Linux is easier to confuse and a little more summarized here.
The address translation functions are converted in the text expressions of the addresses and binary values that they hold in the socket address structure .
There are four address conversion functions: INET_ADDR and Inet_ntoa are suitable for Ipv4,inet_pton and inet_ntop and are suitable for both IPv4 and IPV6.
- The socket address structure is divided into IPV4 socket address structure sockaddr_in and IPV6 socket address structure sockaddr_in6. Where the IPV4 socket address structure is as follows.
- IPV4 Socket Address structure: (defined in the <netinet/in.h> header file)
1 structin_addr{2 in_addr_t s_addr; //3 };4 5 structsockaddr_in{6 uint8_t Sin_len;7 sa_family_t sin_family; Address families for socket address structures8 in_port_t sin_port//tcp or UDP port, typically uint16_t9 struct inch_addr sin_addr; IPV4 address, typically uint32_tTen Charsin_zero[8]; One};
Description: The POSIX specification requires only 3 fields in this structure: sin_family, sin_addr, and Sin_port. For POSIX-compliant implementations, it is acceptable to define additional structure fields. Almost all implementations increase the Sin_zero field, so all socket address structures are at least 16 bytes in size.
- IPV4 addresses and TCP or UDP port numbers are always stored in the network byte order in the socket address structure, which you must keep in mind when using these fields.
- There are two different access methods for 32-bit IPV4 addresses. For example, if serv first has an internetwork socket address structure, SERV.SIN_ADDR will refer to the 32-bit IPV4 address in in_addr structure, and serv.sin_addr.s_addr will press in_addr_t (usually a uint32_ T) refers to the same 32-bit IPV4 address. It is important to use the correct IPV4 address when using it as a parameter of a function, because the compiler handles the transfer structure and passes a positive number completely differently.
- The Sin_zero field has not been used, but when filling out this socket address structure, always set the field to 0 (always set the entire structure to 0 before filling)
- The socket address structure is used only on a given host : although some fields in the structure, such as the IP address and port number, are used for communication between different hosts, the structure itself is not passed between hosts.
- Universal Socket Address Structure:
- When passed into any socket function as a parameter, the socket address structure is always passed in a reference form (that is, a pointer to the struct). However, any socket function with such a pointer as one of the parameters must handle the socket address structure from any of the supported protocol families. There is a problem with how to declare the data type of the passed pointer, with the ANSI C workaround: void *. However, the workaround before ANSI C is to define a common socket address structure in <sys/socket.h>:
1 struct sockaddr {2 uint8_t Sa_len; 3 sa_family_t sa_family; 4 Char sa_data[]; 5 };
The socket function is then defined as one of its parameters as a pointer to a common socket address structure, such as the ANSI C function prototype of the BIND function:
int bind (intstruct sockaddr *, socklen_t); It's usually uint32_t.
This requires that any call to these functions be forced to cast a pointer to a protocol-specific socket address structure into a pointer to a generic socket address type, such as:
struct sockaddr_in Serv;bind (SOCKFD, (structsizeof(serv));
- value-result parameter
- changes the size of the socket address structure from an integer to a pointer to an integer variable, because when the singular is called, the size of the structure is a value that tells the size of the kernel structure so that the kernel does not cross-border when it writes the structure, and when the function returns, The size of the structure is another result that tells the process kernel exactly how much information is stored in the structure. This type of parameter becomes a value-result parameter.
Network byte order <--> host byte order: there are four functions for converting between network byte order and host byte order:
- All of the following two return network byte order
- uint16_t htons (uint16_t host16bitvalue);
- uint32_t htonl (uint32_t host32bitvalue);
- The following two all return host byte order
- uint16_t Ntohs (uint16_t net16bitvalue);
- uint32_t Ntohs (uint32_t net32bitvalue);
Address conversion functions (two groups):
- Inet_aton, inet_addr, Inet_ntoa: This set of functions converts the IPv4 address between a dotted decimal string ("206.168.112.96") and a network byte-order binary value whose length is 32 bits. The prototype is as follows:
#include <arpa/inet.h>int Inet_aton ( const char *strptr, struct in_addr *ADDRPTR); Returns: 1 if the string is valid, otherwise 0in_addr_t inet_addr ( const char *strptr); Returns: The IPV4 address of the 32-bit binary network byte order if the string is valid, otherwise inaddr_none char *inet_ntoa (struct in_addr inaddr); Return: Pointer to a dotted decimal string
//A function named Inet_network is similar to inet_addr, but it returns the host byte order
in_addr_t inet_network (const char *STRPTR);
The
Inet_aton and inet_addr two functions convert a dotted decimal string into a 32-bit network byte-order binary value. Inet_aton function, if the addrptr pointer is empty, the function still performs a validity check on the input string, but does not store any results. There are some problems with the INET_ADDR function: all 2^32 possible binary values are valid IP addresses (0.0.0.0-255.255.255.255), but when an error occurs, the function returns a Inaddr_none constant (usually a 32-bit value of 1). This means that the dotted decimal string 255.255.255.255 cannot be handled by the function because its binary is used to indicate that the function failed, and there is a potential problem with INET_ADDR: Some manuals declare that the function returns 1 instead of Inaddr_none when an error occurs. This can cause problems when comparing the return value of the function to a negative constant. Now that the inet_addr is obsolete, the new code should instead use the Inet_ato function, and a better workaround would be using the Inet_pton function. It is also important to note that the parameters of the Inet_ntoa function are in_addr structures rather than pointers.
- Inet_pton,inet_ntop This set of functions applies to both IPV4 and IPV6 addresses. The prototype is as follows:
#include <arpa/inet.h>int inet_pton (intconstcharvoid * ADDRPTR); Return: 1 If successful, if the input is not a valid expression format is 0, if the error is-1constchar *inet_ntop (intvoid Char *strptr, size_t len); Returns: A pointer to the result if successful, or null if an error occurs
- Address Translation Function Summary:
Inet_pton (af_inet), Inet_aton, inet_addr dot decimal number ----------------------------------------------- ------> in_addr{} IPv4 address <----------------------------------------------------- 32-bit binary IPv4 address inet_ntop (af_inet), Inet_ntoa
#include <stdio.h>#include<string.h>#include<arpa/inet.h>intMainintargcChar**argv) { Const Char*ip_str ="127.0.0.1"; Char*Ip_res; in_addr_t addr_t; structin_addr addr; //binary 1.strInet_aton (IP_STR, &addr); printf ("inet_aton::%x\n", addr); 1000007f addr_t=inet_addr (IP_STR); printf ("inet_addr::%x\n", addr_t); 1000007f Inet_pton (Af_inet, Ip_str, (void*) &addr); 1000007f printf ("inet_pton::%x\n", addr); //2.binary-StrIp_res =Inet_ntoa (addr); printf ("inet_ntoa::%s\n", Ip_res); 127.0.0.1 inet_ntop (Af_inet,&addr, ip_res, Inet_addrstrlen); printf ("inet_ntop::%s\n", Ip_res); 127.0.0.1return 0;} Output:inet_aton::100007finet_addr::100007finet_pton::100007finet_ntoa::127.0.0.1inet_ntop::127.0.0.1
Conversion between IP (dotted decimal <==> binary integers)