Recvmsg and SENDMSG functions
#include <sys/types.h>#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags);ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
These two functions encapsulate most of the parameters in a MSGHDR structure:
struct Msghdr {void *msg_name; Protocol address socklen_t Msg_namelen; Size of protocol address struct Iovec *msg_iov; Scatter/gather array int msg_iovlen; Elements in Msg_iov void *msg_control; Ancillary data (cmsghdr struct) socklen_t Msg_controllen; Length of ancillary data int msg_flags; Flags returned by Recvmsg ()};
- The two members of the Msg_name and Msg_namelen are used in situations where the socket is not connected (such as a UDP socket is not connected). They are similar to the fifth and sixth parameters of Recvfrom and sendto:
- Msg_name points to a socket address structure in which the caller holds the protocol address of the recipient (for sendmsg calls) or the sender (for recvmsg calls). If you do not need to specify a protocol address (such as for a TCP socket or a connected UDP socket), msg_name should be placed as a null pointer.
- Msg_namelen is a value parameter for sendmsg and is a value-result parameter for recvmsg.
- The two members of the Msg_iov and Msg_iovlen specify an array of input or output buffers (that is, an array of IOVEC structures), similar to the second and third parameters of Readv or Writev.
- The two members of Msg_control and Msg_controllen specify the location and size of the optional secondary data. Msg_controllen is a value-result parameter for recvmsg.
For recvmsg and sendmsg, you must distinguish between their two flag variables:
- One is the flags parameter that passes the value;
- The other is the Msg_flags member of the passed MSGHDR struct, which passes the reference, because the address of the struct is passed to the function.
- Only recvmsg use Msg_flags members. When Recvmsg is called, the flags parameter is copied to the Msg_flags member, and the kernel uses its value to drive the receive process. The kernel also updates the values of Msg_flags members based on the results of recvmsg.
- Sendmsg ignores the Msg_flags member because it directly uses the flags parameter to drive the send process. This means that if you want to set the MSG_DONTWAIT flag in a sendmsg call, set the flags parameter to that value and set the Msg_flags member to that value without effect.
The 7 flags returned by RECVMSG are as follows:
- Msg_bcast: This symbol is introduced with Bsd/os, relatively new. Its return condition is that this packet is received as a link-layer broadcast or its destination IP address is a broadcast address. This flag is a better way to determine whether a UPD packet is destined for a broadcast address than the IP_RECVD-STADDR socket option.
- Msg_mcast: This symbol is introduced with Bsd/os, relatively new. Its return condition is that this datagram is charged as a link-layer multicast.
- Msg_trunc: The return condition of this flag is that this datagram is truncated, that is, the data that the kernel prepares to return exceeds the space previously allocated by the process (sum of all Iov_len members).
- Msg_ctrunc: The return condition of this flag is that the secondary data of this datagram is truncated, that is, the secondary data that the kernel prepares to return exceeds the pre-allocated space of the process (Msg_controllen).
- Msg_eor: The return condition of this flag is a logical record that returns the end of data. TCP does not use this flag because it is a byte stream protocol.
- Msg_oob: This flag is never returned for TCP out-of-band data. It is used for other protocol families (such as the OSI protocol family).
- Msg_notification: This flag is returned by the SCTP receiver, indicating that the read-in message is a prior notification, not a data message.
Shows a MSGHDR structure and the various information it points to. The diagram assumes that the process is about to call recvmsg on a UDP socket:
The diagram assigns 16 bytes to the protocol address and allocates 20 bytes to the secondary data. Initializes an array of 3 IOVEC structures for buffered data: The first one specifies a 100-byte buffer, the second specifies a 60-byte buffer, and the third specifies a 80-byte buffer. Assume that the IP_RECVDSTADDR socket option has been set for this socket to receive the destination IP address of the UDP packet being read.
Assuming that a 170-byte UDP datagram is reached from 198.38.100:2000, it is destined for our UDP socket with the destination IP address 206.168.112.96. Shows all the information in the MSGHDR structure when Recvmsg returns.
The Recvmsg modified fields are shaded in the figure. The changes from the first picture to the second picture include the following points:
- The buffer pointed to by the Msg_name member is populated with an internetwork socket address structure, which has the source IP address and the source UPD port number that received the datagram.
- The Msg_namelen member (a value-result parameter) is updated to the amount of data stored in the Msg_name buffer. There is no change to this member because the value is 16 before and after the recvmsg call.
- The first 100 bytes of data to be collected are stored in a buffer, where 60 bytes of data are stored in the second buffer, and the last 10 bytes of data are stored in a third buffer. The last 70 bytes of the buffer are unchanged. The return value of the RECVMSG function, or 170, is the size of the datagram.
- The buffer pointed by the Msg_control member is filled with a CMSGHDR structure. In the CMSGHDR structure, the Cmsg_len member value is 16,cmsg_level member value of Ipproto_ip,cmsg_type member value is IP_RECVDSTADDR, followed by 4 bytes to hold the destination IP address of the received UDP datagram. The latter 4 bytes of this 20-byte buffer are unchanged.
- The Msg_controllen member is updated to the actual amount of data stored in the secondary data. This member is also a value-result parameter, and the result is 16 when Recvmsg returns.
- Msg_flags members are also updated by RECVMSG, but no flags are returned to the process.
Recvmsg and SENDMSG functions of Linux programming