[TCP / IP] network programming: 03 address family and sequence data

Previous article describes the process of creating a socket, this article focuses on the distribution of knowledge to the socket IP address and port number.

IP address and port number

IP (Internet Protocol, Internet Protocol) address is the network send and receive data value assigned to the computer, the port number is not given the value of the computer, but to distinguish between different sockets computer program created and assigned to the socket number .

website address

IP addresses are divided into two categories, which, IPv6 is the new standard in order to deal with the problem after the 2010 IP address exhaustion proposed. However, mainly IPv4, IPv6 popularity may be some time before the current widespread use.

  IPv4 (Internet Protocol version 4) 4-byte address family

  IPv6 (Internet Protocol version 6) 16-byte address family

Standard 4-byte IPv4 IP addresses and host addresses of networks, where the network address is divided into A, B, C, D and other types, the following structure:

 IPv4 address family

Why IP address to be divided into network and host addresses? Network address part of the IP address to distinguish between the different network settings, imagine if all 4-byte IP address of the host address, then the communication between computers pathfinding will become very inefficient. To join the network address of the communication path-finding process is divided into two parts, first lock the valid network address, and then find the host address, effectively improve the communication efficiency. For example, a host transmitting data to 203.211.172.103 203.211.217.202 and wherein 203.211.172 203.211.217 and a network address. As can be seen from the figure, the node network address is composed of a router or switch, the router receiving data and then transmit the data to the target host from the host address data.

Network address mentioned above and is 203.211.172 203.211.217, how to distinguish their types? We just need to focus on value to the first byte of the IP address:

  Class A addresses the first byte range: 0 to 127  0 000 0000 ~ 0111111111

  Class B address the first byte range: 128 - 191    10 00 0000 ~ 1011111111

  Class C address of the first byte range: 192 to 223    110 0 0000 ~ 1101111111

In addition, according to the number of bytes above the share of different types of network addresses, to know the Class A address is the most valuable, because it has the most abundant IP address resources. A Class A address 256 corresponding to class B, the same, a class B address 256 corresponds to class C address.

The port number

IP address is used to distinguish a computer, as long as the IP address of the host can transmit data to the target, but this alone does not determine the specific program. For example, when Chiang Kai-shek computer running chat programs and browser program, then the computer how to decide which programs to receive network data sent to it?

It is generally equipped with a computer NIC (Network Interface Card, a network interface card) data transmission device uses an IP address to the internal data transmission of the computer through the NIC. The operating system is responsible for the specific allocation of internal data to the socket, then you need to use the port number as a distinction. The entire data allocation process is as follows:

Port number is the same operating system in order to differentiate the provided socket can not assign a different port number to the socket (due to UDP and TCP socket socket port number not be shared, can be repeated) . Port number composed of 16 bits, ranging from 0 to 65,535, but is 0 to 1023 using the well-known port number of a particular program, the value is outside this range should be used.

Represents address information

Article mentioned previously and sockaddr_in sockaddr, given the following definition of the structure related

// IPv4 address structure 
struct sockaddr_in
{
    sa_family_t    sin_family;       //地址族
    uint16_t     sin_port;        //16位端口号,网络序保存
    struct in_addr sin_addr;         //32位IP地址,网络序保存
    char        sin_zero[8];     //保留
}

//通用地址结构
struct sockaddr
{
    sa_family_t    sin_family;     //地址族
    char           sa_data[14];    //地址信息
}

struct in_addr
{
   in_addr_t    s_addr;    //32位IPv4地址
}

以上结构体定义中涉及到的数据类型如uint16_t、in_addr_t等,可参考POSIX(Portable Operating System Interface,可移植操作系统接口)。之所以有这些定义,是考虑到移植性的结果,如uint16_t,不论是在32位系统中还是在64位系统中其对应数据类型均是16位无符号整形。POSIX中的一些数据类型定义如下:

之前的文章中有提到sockaddr_in和sockaddr的区别的问题,结合上面的结构体定义可知,sockaddr_in是IPv4地址信息专用的结构体;而sockaddr则是兼容除IPv4地址信息之外的结构体(不过从地址信息字节大小14个字节来看,似乎并不兼容IPv6)。

网络字节序与地址转换

字节序,简单来说就是一个数据的高低字节在内存中的存储及解析方式。字节序分为如下两种方方式:

  大端序(Big Endian):高位字节存放在低位地址

  小端序(Little Endian):低位字节存放在高位地址

单字节数据的大小端存储方式并没有区别,多字节数据的大小端存储方式则截然不同。如一个4字节整型值0x12345678的高字节数据0x12,大端存储时在内存的低地址端,而小端存储则正好相反:

 

大端序存储和小端序存储

为什么计算机通信需要字节序转换?如果发生数据交换的两台计算机有不同的字节序存储方式会发生什么?

 不同字节序的计算机发生数据交换时引发的错误

正如上图所发生的那样,大端序系统的数据传输到小端序系统,原来的数据0x1234被错误地解析为0x3412。这显然不是我们所期望得到的结果,因此当需要在不同的计算机间传输数据时,我们要时刻铭记字节序的转换。而考虑到程序的可移植性,即使我们已知通信双方主机拥有相同字节序,我们仍需做字节序转换的操作。进一步,当有数据需要保存并且有可能在其他主机上恢复时,我们也需要考虑字节序转换的操作。

实际上,在网络编程中,我们只需要考虑向sockaddr_in结构体变量填充数据时的字节序转换,而真正传输数据的字节序转换是底层机制自动完成的。

网络地址的初始化

sockaddr_in中保存的地址信息成员为32位整型值,而我们熟悉的是点分十进制(Dotted Decimal Notation)这种字符串表示方法,因此需要做相应的装换。下面介绍的一些函数将帮助我们完成这些装换

#include <arpa/inet.h>

in_addr_t inet_addr(const char *string);
    -> 成功时返回32位大端序整型值,失败时返回INADDR_NONE
#include <arpa/inet.h>

int inet_aton(const char *string, struct in_addr *addr);
    -> 成功时返回1(True),失败时返回0(Flase)
#include <arpa/inet.h>

char *inet_ntoa(struct in_addr addr);
    -> 成功时返回转换的字符串首地址,失败时返回-1

函数inet_addr和inet_aton在功能上完全相同,不过函数inet_aton可以直接返回in_addr结构体,即直接传入sockaddr_in中地址成员sin_addr的地址即可保存地址值。函数inet_ntoa则恰好与inet_aton相反,完成网络地址从32位整型值到点分十进制的字符串的转换。不过函数inet_ntoa所返回的字符串只是存储在内部临时的内存空间中,一旦下次被调用,则之前的转换字符串将被覆盖。因此,对于函数inet_ntoa的返回值我们应及时copy到自己的存储空间中。

网络地址初始化

struct sockaddr_in serv_addr;
char *serv_ip = "192.168.158.10";
char *serv_port = "8080";
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(serv_ip);
serv_addr.sin_port = htons(atoi(serv_port));

sockaddr_in address when bound to the socket socket, you need to initialize and assignment. memset will sockaddr_in all values ​​set to zero memory space, mainly to sockaddr_in no use to the first four reserved parameters sin_zero set to 0, otherwise it may cause some unknown error (such as garbage value in the course of the sockaddr structure converted introduced the impact of).

INADDR_ANY

Before the series of articles mentioned Reflections on INADDR_ANY address INADDR_ANY role is to run the server can automatically obtain the IP address of the computer. If the same machine is assigned a plurality of IP addresses (multihomed (Multi-homed) computers, routers typically fall into this category), the same port number as long as it can receive data from different IP addresses. Therefore, the server will give priority in this way.

Create a server socket why you need to configure IP addresses? As described above, the same computer can assign multiple IP addresses, NIC number equal to the number of the actual IP address of the computer installation, and therefore, even if the server needs to be determined receives the IP data transmitted. If the server has only one NIC, you can simply use INADDR_ANY can.

About 127.0.0.1 address

127.0.0.1 is the loopback address (loopback address), refers to the computer's own IP address. If the client and server are running on the same computer, computers using the replacement address of the actual IP address still operate normally.

Guess you like

Origin www.cnblogs.com/Glory-D/p/11831276.html