The socket call receives data and control information on a specified socket.
Syntax
#include <types.h> #include <sys\socket.h> int recvmsg(s, msg, flags) int s; struct msghdr *msg; int flags;
Parameters
s
MSG_DONTWAIT
Description
This call receives a message on a socket with descriptor s.
Networking services supports the following msghdr structure.
Note: The fields msg_control and msg_controllen are ignored for the NetBIOS and Local IPC domains.
struct msghdr { caddr_t msg_name; /* optional pointer to destination address buffer */ int msg_namelen; /* size of address buffer */ struct iovec *msg_iov; /* scatter/gather array */ int msg_iovlen; /* number of elements in msg_iov, maximum 1024 */ caddr_t msg_control; /* ancillary data */ u_int msg_controllen; /* ancillary data length */ int msg_flags; /* flags on receive message */ };
msg_iov is a scatter/gather array of iovec structures. The iovec structure is defined in <SYS/UIO.H> and contains the following fields:
Field
TCP/IP alters iov_base and iov_len for each element in the input struct iovec array. iov_base will point to the next character of the processed (sent or received) data on the original buffer, and iov_len will become (input value - processed length). Thus if only partial data has been sent or received and the application expects more data to send or receive, it can pass the same iovec structure back in a subsequent call.
The recvmsg() call applies to connection-oriented or connectionless sockets.
This call returns the length of the data received. If a datagram or sequenced packet is too long to fit in the supplied buffer, the excess is discarded. No data is discarded for stream sockets. If data is not available at the socket with descriptor s, the recvmsg() call waits for a message to arrive and blocks the caller, unless the socket is in nonblocking mode. See ioctl() for a description of how to set nonblocking mode.
Return Values
When successful, the number of bytes of data received into the buffer is returned. The value 0 indicates the connection is closed; the value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno().
Error Code
Examples
The following is an example of using recvmsg() call to receive token ring routing information in the msg_control buffers:
Exampleofrecvmsg ( )Call
char buf[50], control_buf[100]; main(int argc, char *argv[]) { struct sockaddr_in server; int optlen, smsg, byterecv,rv,i, ip_recvtrri; struct msghdr msg; struct cmsghdr *cmsg; struct iovec iov; struct timeval tv; if ((smsg = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) psock_errno("Socket()"); server.sin_len = sizeof(struct sockaddr); server.sin_family = AF_INET; server.sin_port = htons(atoi(argv[1])); /* port number */ server.sin_addr.s_addr = INADDR_ANY; if (bind(smsg, (struct sockaddr *)&server , sizeof(server)) < 0) psock_errno("bind()"); iov.iov_base = buf; iov.iov_len = sizeof(buf)-1; msg.msg_name = NULL; msg.msg_namelen = sizeof(struct sockaddr); msg.msg_iov = &iov msg.msg_iovlen = 1; msg.msg_control = control_buf; msg.msg_controllen = sizeof(struct cmsghdr)+4+18;/*4 byte ipaddr + 18 TRRI*/ ip_recvtrri = 1; if (setsockopt(smsg,IPPROTO_IP,IP_RECVTRRI,(char *)&ip_recvtrri , sizeof(ip_recvtrri)) < 0) psock_errno("setsockopt() IP_RECVTRRI"); /* Set another IP socket options for timeout so we do not block waiting */ tv.tv_sec = 10; /* Wait for max 10 sec on recvmsg */ tv.tv_usec = 0; rv = setsockopt(smsg, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof(struct timeval)); if (rv < 0) psock_errno("Set SO_RCVTIMEO"); if((byterecv=recvmsg(smsg, &msg, 0))<0) psock_errno("recvmsg()"); else { cmsg = (struct cmsghdr *) msg.msg_control; printf(" IP_RECV TR RI (data in network byte order): "); for (i=sizeof(struct cmsghdr); i < cmsg->cmsg_len;i++) printf(" %x",msg.msg_control[i]); } soclose(smsg); }
Related Calls
connect()
getsockopt()
ioctl()
os2_ioctl()
recv()
recvfrom()
select()
send()
sendmsg()
sendto()
shutdown()
sock_errno()
socket()