Struct msghdr and struct cmsghdr [Reproduced]

Source: Internet
Author: User
Tags sendmsg

Understanding struct msghdr
When I first saw him, it seemed like a huge structure to be created. But don't be afraid. Its structure is defined as follows:
Struct msghdr {
Void * msg_name;
Socklen_t msg_namelen;
Struct iovec * msg_iov;
Size_t msg_iovlen;
Void * msg_control;
Size_t msg_controllen;
Int msg_flags;
};
The structure members can be divided into four groups. They are:
Set the interface address members msg_name and msg_namelen.
The I/O vector references msg_iov and msg_iovlen.
Msg_control and msg_controllen of the attached data buffer.
The receiving information flag msg_flags.
After we divide this structure into the above categories, the structure will not look so huge.
Msg_name and msg_namelen
These members are only required when our set interface is a datagram set interface. The msg_name Member points to the set interface address for sending or receiving information. Msg_namelen indicates the length of the interface address.
When recvmsg is called, msg_name points to the receiving region of the address to be received. When sendmsg is called, this directs to the destination address to which the datagram will be sent.
Note that msg_name is defined as a (void *) data type. We do not need to convert our set of interface addresses to (struct sockaddr *).
Msg_iov and msg_iovlen
These members specify the position of our I/O Vector Array and the number of items it contains. The msg_iov Member points to a struct iovec array. We will recall that the I/O vector points to our buffer zone. Msg_iov indicates the number of elements in our I/O Vector Array.
Msg_control and msg_controllen members
These members point to our affiliated data buffer and indicate the buffer size. Msg_control points to the secondary data buffer, while msg_controllen indicates the buffer size.
Msg_flags
When recvmsg is used, this member is used to receive a specific tag bit (which is not used for sendmsg ). The following table lists the markup bits that can be received at this position:
Tag description
Msg_eor is set when the end of the received record is reached. This is usually useful for the sock_seqpacket interface type.
Msg_trunc indicates that the end of the data is truncated because the receiving buffer is too small to receive all the data.
Msg_ctrunc indicates that some control data (ancillary data) is truncated because the buffer zone is too small.
MSG_OOB indicates that out-of-band data is received.
Msg_errqueue indicates that no data is received, but an extension error is returned.
You can view more information on the man manual page of recvmsg (2) and sendmsg (2.
Subsidiary data structure and macro
The recvmsg and sendmsg functions allow the program to send or receive ancillary data. However, these additional information is limited by certain format rules. This section describes the macros used to control information headers and programs to manage such information.
Introduction to struct cmsghdr Structure
Appendix
The owner information can include 0, 1, or more independent affiliated data objects. There is a struct before each object.
Cmsghdr structure. The header is followed by the padding byte and then the object itself. Finally, more bytes may be filled before the next cmsghdr after the affiliated data object. In this chapter, we will
The affiliated data objects to be concerned are file descriptors and certificate structure.
Shows how a buffer that contains ancillary data is organized.
Note the following:
The length of the cmsg_len and cmsg_len () macro values is the same.
The cmsg_space () macro can calculate the required blank space of an affiliated data object.
Msg_controllen is the length of cmsg_space () and is calculated for each affiliated data object.
The control information header is defined by the following C structure:
Struct cmsghdr {
Socklen_t cmsg_len;
Int cmsg_level;
Int cmsg_type;
/* U_char cmsg_data []; */
};
The members are described as follows:
Member description
The Byte Count of the cmsg_len ancillary data, which contains the size of the structure header. This value is calculated by the cmsg_len () Macro.
The cmsg_level value indicates the original protocol level (for example, sol_socket ).
The value cmsg_type indicates the type of the control information (for example, scm_rights ).
The cmsg_data member does not actually exist. It is used to specify the location of the actual additional ancillary data.
The example program used in this chapter only uses the cmsg_level value of sol_socket. In this chapter, we are interested in the following types of control information (cmsg_level = sol_socket ):
Cmsg_level description
The scm_rights data object is a file descriptor.
The scm_credentials data object is a structure containing certificate information.
Introduction cmsg (3) Macro
Due to the complexity of the ancillary data structure, Linux provides a series of C macros to simplify our work. In addition, these macros can be transplanted between different UNIX platforms and some measures have been taken to prevent future changes. These macros are described on the man manual page of cmsg (3). Their overview is as follows:
# Include
Struct cmsghdr * cmsg_firsthdr (struct msghdr * msgh );
Struct cmsghdr * cmsg_nxthdr (struct msghdr * msgh, struct cmsghdr * cmsg );
Size_t cmsg_align (size_t length );
Size_t cmsg_space (size_t length );
Size_t cmsg_len (size_t length );
Void * cmsg_data (struct cmsghdr * cmsg );
Cmsg_len () Macro
This macro accepts the object size we want to place in the attached data buffer as input parameters. If we review a previous introduction, we will find that this macro will calculate the length of the cmsghdr header structure plus the byte length of the required characters. This value is used to set the cmsg_len Member of the cmsghdr object.
The following example demonstrates how to calculate the value of the cmsg_len member if the ancillary data is a file descriptor:
Int FD;/* file descriptor */
Printf ("cmsg_len = % d/N", cmsg_len (sizeof FD ));
Cmsg_space () Macro
This macro is used to calculate the affiliated data and the total white space required by its header. Although the cmsg_len () macro calculates a similar length, the cmsg_len () value does not include possible trailing padding characters. The cmsg_space () macro is very useful for determining the required buffer size, as shown in the following sample code:
Int FD;/* file descriptor */
Char abuf [cmsg_space (sizeof FD)];
In this example, abuf [] declares sufficient buffer space to store the header, the padding byte, the ancillary data itself, and the final padding byte. If there are multiple ancillary data objects in the buffer, you must add multiple cmsg_space () macro calls at the same time to obtain the total space required.
Cmsg_data () Macro
This macro accepts a pointer to the cmsghdr structure. The returned pointer value points to the first byte (if any) of the affiliated data following the header and after the byte filling ). If the pointer mptr points to a header that describes the available ancillary data of the file descriptor, the file descriptor can be obtained using the following code:
Struct cmsgptr * mptr;
Int FD;/* file descriptor */
...
FD = * (int *) cmsg_data (mptr );
Cmsg_align () Macro
This is a Linux expansion macro, not part of the posix.1g standard. Specify a byte length as the input. This macro calculates a new length, which includes the additional Padding Bytes required to maintain alignment.
Cmsg_firsthdr () Macro
This
Returns a struct cmsghdr pointer to the First Affiliated object in the attached data buffer. The input value is to struct.
Msghdr structure pointer (not with struct
Cmsghdr ). This macro will estimate msg_control and msg_controllen members of msghdr to determine whether there are any attached objects in the buffer. However
Then, it calculates the returned pointer.
If no ancillary data object exists, the returned pointer value is null. Otherwise, the Pointer Points to the existing first struct cmsghdr. This macro is used at the beginning of a for loop to start traversing in the affiliated data object.
Cmsg_nxthdr () Macro
Returns the struct cmsghdr pointer of the next affiliated data object. This macro will accept two input parameters:
Pointer to the struct msghdr Structure
Pointer to the current struct cmsghdr
If no ancillary data object exists, the macro returns NULL.
Traverse affiliated data
When receiving an affiliated data, we can use the cmsg_firsthdr () and cmsg_nxthdr () macros to traverse the affiliated data objects. The following sample code shows the common format of the for loop and the corresponding usage of macros:
Struct msghdr msgh;/* message HDR */
Struct cmsghdr * cmsg; 0/* PTR to ancillary HDR */
Int * fd_ptr;/* PTR to file descript .*/
Int inclued_fd;/* the file descriptor */
For (cmsg = cmsg_firsthdr (& msgh); cmsg! = NULL; cmsg = cmsg_nxthdr (& msgh, cmsg )){
If (cmsg-> cmsg_level = sol_socket & cmsg-> cmsg_type = scm_rights ){
Fd_ptr = (int *) cmsg_data (cmsg );
Received_fd = * fd_ptr;
Break;
}
}
If (cmsg = NULL ){
/* Error: No file descriptor Recv 'd */
}
Create affiliated data
The process that sends a file descriptor must use the correct formatted data to create a secondary data buffer. The following code shows the general creation process:
Struct msghdr MSG;/* message header */
Struct cmsghdr * cmsg;/* PTR to ancillary HDR */
Int FD;/* file descriptor to send */
Char Buf [cmsg_space (sizeof FD)];/* ANC. Buf */
Int * fd_ptr;/* PTR to file descriptor */
MSG. msg_control = Buf;
MSG. msg_controllen = sizeof Buf;
Cmsg = cmsg_firsthdr (& MSG );
Cmsg-> cmsg_level = sol_socket;
Cmsg-> cmsg_type = scm_rights;
Cmsg-> cmsg_len = cmsg_len (sizeof FD );
/* Initialize the payload :*/
Fd_ptr = (int *) cmsg_data (cmsg );
* Fd_ptr = FD;
/*
* Sum of the length of all control
* Messages in the buffer:
*/
MSG. msg_controllen = cmsg-> cmsg_len;

Struct msghdr and struct cmsghdr [Reproduced]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.