Basic knowledge of socket programming

Insist on studying every day and keep on blogging.
Come on February

Socket address structure

        Socket programming needs to specify the address of the socket as a parameter. Different protocol families have different ways of defining the address structure. These address structures usually start with sockaddr_, and each protocol family has a unique suffix. For example, for Ethernet, the structure name is sockaddr_in.

General socket data structure

The general socket address type is defined as follows, it can be forcibly converted between different protocol families. '

struct sockaddr{
    
    	//套接字地址结构
	sa_family_t  sa_family;		//协议族
	char         sa_data[14];	//协议族数据
};

        The type of the protocol family member variable sa_family in the above structure is sa_family_t. In fact, this type is an unsigned short type, so the length of the member variable sa_family is 16 bytes.

typedef unsigned short sa_family_t;

The actual socket data structure used

        Almost all socket functions in the functions used in network programming use this structure as a parameter. For example, the prototype of the bind() function is:

int bind(int sockfd,	//套接字文件描述符
	const struct sockaddr *my_addr,	//套接字地址结构
	socklen_t addrlen);	//套接字地址结构的长度

        However, it is not convenient to use the structure struct sockaddr to set up. In Ethernet, the structure struct sockaddr_in is generally used for setting. The definition of this structure is as follows:

struct sockaddr_in{
    
    	//以太网套接字地址结构
	u8    sin_len;	//结构 struct sockaddr_in的长度,16
	u8    sin_family;	//通常为AF_INET
	u16   sin_port;	//16位的端口号,网络字节序
	struct in_addr sin_addr;	//IP地址32位
	char  sin_zero[8];	//未用
};

The member in_addr of the structure struct sockaddr_in is used to represent the IP address. The definition of this structure is as follows:

struct in_addr{
    
    	//IP地址结构
	u32 s_addr;	//32位IP地址,网络字节序
};

The relationship between structure sockaddr and structure sockaddr_in

        The structure struct sockaddr and the structure struct sockaddr_in are a structure of the same size. For the corresponding relationship, see the
Insert picture description here
meaning of the members in the figure struct sockaddr_in as follows.

  • sin_len: unsigned character type, representing the length of the structure struct sockaddr_in, which is 16.
  • sin_family: unsigned character type, usually set to be consistent with the domain of the socket() function, such as AF_INET.
  • sin_port: unsigned short type, representing port number, network byte order
  • sin_addr: struct in_addr type, its member s_addr is an unsigned 32-bit number, each 8 bits represents a segment of the IP address, and the network byte order.
  • sin_zero[8]: char type, reserved.

        Since the size of the structure struct sockaddr and the structure struct sockaddr_in are exactly the same, when setting the address structure, the usual method is to use the structure struct sockaddr_in to set it, and then force the conversion of the bit structure struct sockaddr type. Because the sizes of these two structures are exactly the same, there will be no side effects in performing such a conversion.

User layer and kernel layer exchange process

        There are some parameters in the socket parameters that need to be passed in by the user. These parameters are used to communicate with the Linux kernel, such as a pointer to an address structure. It is usually carried out by means of memory copy. For example, the bind() function needs to pass in the address structure struct sockaddr *my_addr and my_addr to point to the length of the parameter.

The interactive process of passing data to the kernel

        The functions that pass data to the kernel include send(), bind(), etc., and the functions that get data from the kernel include accept(), recv(), etc. The incoming process is shown in the figure. The parameters passed by the bind() function to the kernel are related to the socket address structure and the length of the structure.

Insert picture description here
        The parameter addlen represents the length of the address structure, and the parameter my_addr is a pointer to the address structure. When the function bind() is called, the content of the address structure is copied to the kernel by memory copy, the length of the address structure is passed to the kernel by value, and the kernel copies the socket according to the length of the address structure passed by the user The content of the address structure.

The interactive process of data from the kernel

        The process of transferring parameters from the kernel to the user space is reversed. The process of transferring is shown in the figure. The transfer of the address structure parameters is carried out through the length of the address structure and the socket address structure pointer. Usually two parameters complete the function of the outgoing operation, one indicates the parameter of the address length, and the other indicates the pointer of the socket address structure address.
Insert picture description here
        The difference between the parameters of the outgoing process and the incoming process is that the parameter representing the length of the address structure is passed by value during the incoming process, but is completed by addressing during the outgoing process. The kernel copies the socket address structure data according to the length of the address structure passed in by the user, and copies the address structure data in the kernel to the address structure pointer passed in by the user.

Guess you like

Origin blog.csdn.net/zouchengzhi1021/article/details/113488273