Explain the ip address in a simple way!

Foreword:

In the previous article, I gave you some code examples, but the system interface in the code did not give you a detailed explanation, so this article will give you a detailed explanation!

First, look at the socket() interface first:

Through the previous article, we now know that before network communication, we will call the socket() interface to make preparations. What preparations should we make? That is to apply for system resources to the system, so that we can perform network programming:

int socket(int domain, int type , int protocol);

At the same time, we also know that socket is a multi-functional communication capability, such as:

  • network programming
  • local interprocess communication

What if I don't want the network programming function and want to communicate locally between processes? That is, when calling the socket() interface, just replace the passed parameters.

So let's take a look at the meaning of the parameters passed by the socket interface:

  • domain: The protocol family information used in the socket, for example: PF_INET, what does this mean? It means the Internet communication protocol family based on IPV4. Of course, there is also the Internet communication protocol family of IPV6, but because it is not yet popular, the article mainly focuses on IPV4 for explanation. The following is a summary of common protocol families. Note that the address representations in different protocols may be different. The address type must match the protocol type during network programming. For example, the IP address format of IPV4 is a 4-byte integer, while the IP address of IPV6 This is not the case anymore:
-PF_INET:IPv4互联网协议族
-PF_INET6:IPv6互联网协议族
-PF_LOCAL:本地通信的协议族
-PF_PACKET:底层数据收发协议族
-PF_IPX:Novell专用协议(互联网分组交换协议)
  • type: socket data transfer type information:
-1、SOCK_STREAM: 流式数据(TCP)
-2、SOCK_UGRAM:报文式数据(UDP)
  • protocol: Protocol information used for communication between devices
domain和type几乎可以唯一确定一种协议,因此,这个参数通常为0
,这个0代表的domain和type指定后的默认协议

Through the above detailed introduction, everyone should be very familiar with the socket() interface now!

2. Regarding the port number and IP address:

  • The port number is a 2-byte unsigned integer data
  • 0 - 1023 are predefined (assigned to specific applications) as specific ports (including 1024 -2048), and these specific port numbers cannot be freely used by our programmers, so special attention should be paid to this!
  • The IP address is a 4-byte address family (it can be divided into 5 types of addresses, and the E-type addresses are not drawn here, but there are supplements later):

insert image description here

1. In-depth analysis of IP address:

  • The IP address is divided into two parts: the network identifier and the host identifier: what is the network identifier? Identify the network on which the network host device resides; what is host identification? Identifies the specific address of the network host device. Then the question arises, an IP address is only 4 bytes, so how to distinguish the network identifier from the host identifier?
    Let's look at a picture below:

insert image description here
In general:

  • IP address and subnet mask are used together to distinguish network identification and host identification
  • The representation of the subnet mask is also a 4-byte integer
  • Subnet mask is used to extract network identity from IP address

So how do we extract the network identifier? The general approach is to extract the network identifier through bitwise AND operations, such as the following:

insert image description here
Here we have a deeper understanding of the role of the subnet mask? For example now:

Assumption: the subnet mask is MNPQ; then the subnet available IP address n=(256-M) (256-N) (256-P)*(256-Q)

For example, the current IP address is: 211.99.34.33; the mask is: 255.255.255.248; then the subnet IP address that can be used is 8 IP addresses, and the subnet address of 211.99.34.33 is 211.99.34.32, and the broadcast address is 211.99 .34.39:
insert image description here

A little attention here, 211.99.34.33~211.99.34.38 is what we can use!

Let's take a look at some special IP addresses:

  • 0.0.0.0: reserved, often used to represent the "default network". In server-side programming, if this address is used, it means that the data connected to each network card in the machine must be processed!
  • 127.0.0.0: Loopback address, often used for loopback testing of local software;
  • 255.255.255.255: Indicates the broadcast address

Then there are some private addresses: not used in the public network, only used in the internal network:

  • 10.0.0.0 ~10.255.255.255
  • 172.16.0.0~172.31.255.255
  • 192.168.0.0~192.168.255.255

2. Address data type analysis:

In order to clarify the knowledge points of this address type, let's first look at the following picture:
insert image description here
Seeing this picture, do you understand that there are many interfaces in the code written before that always have an address translation (forced by strcut socket addr_in typecast to struct sockaddr):

int bind(int sock, struct sockaddr *addr , socklen_t addlen);

Well, here, because we focus on IPV4, we still look at this structure:

strcut sockaddr_in 
{
    
    
   sa_family_t sa_family;//具体的哪种地址类型,比如有IPV4地址类型,那么赋值的时候就是AF_INET
   u_int16_t sin_port;//指定端口号
   struct in_addr sin_addr;//指定具体的地址
}

The structure struct in_addr is specifically:

struct in_addr
{
    
    
	u_int32_t s_addr;//这个具体的地址,是4字节的无符号整型数据类型
}

Then there is a problem here, which involves the conversion of the string address "192.168.3.2" and the integer IP address. Here, the problem is mainly solved by function conversion:

#include <arpa/inet.h>

in_addr_t inet_addr(const char * strptr);//将IP字符转串转换为符合网络字节序的整数

int inet_aton(const char* cp, struct in_addr*inp);//将IP字符串转换为符合网络字节序的整数,成功返回1,失败返回0

char * inet_ntoa(struct in_addr in);//将符合网络字节序的整数地址转化为字符串形式

Here is a little trick to distinguish the latter two functions, a represents the address, and n represents the network, so it is easy to distinguish.

Here is an example of an actual code example:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet.in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <malloc.h>

int main()
{
    
    
	unsigned int addr = inet_addr("1.2.3.4");
	struct in_addr addr1 = {
    
    0x09080706};
	struct in_addr addr2 = {
    
    0x05040302};
	char *s1 = strcpy(malloc(32),inet_ntoa(addr1));
	char *s2 =strcpy(malloc(32),inet_ntoa(addr2));
    
    printf("addr = %x\n",addr);
    printf("addr1 = %s\n",s1);
    printf("addr2 = %s\n",s2);
     
    printf("s1 = %s\n",s1);
    printf("s2 = %s\n",s2);
    if(inet_aton("1.2.3.4"),&addr1))
    {
    
    
    	printf("addr1 = %x\n",addr1.s_addr);
    }  
    free(s1);
    free(s2);
    return 0;
}

The result of the operation is as follows:

root@ubuntu:/home/hao/socket# ./a.out 
addr = 4030201
addr1 = 6.7.8.9
addr2 = 2.3.4.5
s1=6.7.8.9
s2=2.3.4.5
addr1 = 4030201

Supongo que te gusta

Origin blog.csdn.net/Dada_ping/article/details/127955485
Recomendado
Clasificación