GuzLightyear
GuzLightyear

Reputation: 31

In Linux, recv() works but recvmsg() doesn't

i've got this code in a function, running on a raspberry Pi:

struct sockaddr_in addr_buffer;
struct cmsghdr control_buffer;
struct msghdr msghdr;
struct iovec iov[1];
char msg_buffer[1458];

memset(&msg_buffer, 0, sizeof(msg_buffer));
memset(iov, 0, sizeof(iov));
memset(&msghdr, 0, sizeof(msghdr));

iov[0].iov_base = msg_buffer;
iov[0].iov_len = sizeof(msg_buffer);

msg.msg_iov = iov;
msg.msg_iovlen = 1;

msghdr.msg_name = &addr_buffer;
msghdr.msg_namelen = sizeof(addr_buffer);
msghdr.msg_control = &control_buffer;
msghdr.msg_controllen = sizeof(control_buffer);
msghdr.msg_flags = 0;

//int msgsize = recv(udpsocket_fd, &msg_buffer, 4, 0);

int msgs_received = recvmsg(udpsocket_fd, &msghdr, 0);

According to what i've read, the recvmsg() system call should return into the iovec pointed by msghdr one message at a time (as the iovec array is 1 unit long). However, it doesn't work: I receive correctly the headers, as I can read using the debugger which IP has sent the packet, but the msg_buffer remains empty. The function also returns 0, which is strange, as it means that no errors have happened (which would return -1), but also means that no messages have been received (though the headers have been updated)

If I uncomment the recv() line, however, it all works as expected, and the message is in msg_buffer. But, obviously, no extra information is received. I have been scratching my head for two hours already and can't see what's wrong with the code. Thanks a lot for the help!

Upvotes: 1

Views: 2061

Answers (1)

bartop
bartop

Reputation: 10315

From what you are showing you are just improperly initializing msghdr. Try adding this before recvmsg call:

mhdr.msg_iov = iov;
mhdr.msg_iovlen = 1;

Upvotes: 1

Related Questions