migrating recvmsg() to recvfrom() 
July 22nd, 2005, 05:44 PM
| | | |
Hi group,
I am trying to port a reliable multicast framework for UNIX to Win32 and so
far so good, but I stumbled on the next problem:
in the original code, the programmers use the recvmsg() function and as far
as I know, there is no Windows-version of this function. So I guess I will
have to translate it to a recvfrom(), but that gives some problems.
First of all, in the man pages I read the following:
<man recvfrom>
int recvfrom(int s, void *buf, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen);
int recvmsg(int s, struct msghdr *msg, int flags);
DESCRIPTION
[...]
The recvmsg call uses a msghdr structure to minimize the
number of directly supplied parameters. This structure
has the following form, as defined in <sys/socket.h>:
struct msghdr {
void * msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec * msg_iov; /* scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void * msg_control; /* ancillary data, see below
*/
socklen_t msg_controllen; /* ancillary data buffer len
*/
int msg_flags; /* flags on received message
*/
};
[...]
The messages are of the form:
struct cmsghdr {
socklen_t cmsg_len; /* data byte count, including hdr
*/
int cmsg_level; /* originating protocol */
int cmsg_type; /* protocol-specific type */
/* followed by
u_char cmsg_data[]; */
};
Ancillary data should only be accessed by the macros
defined in cmsg(3).
[...]
</man recvfrom>
So how do I translate it then?
if the original code is
bytes_read=recvmsg(sd, &msg, 0);
I think it should be the following:
bytes_read=recvmsg(sd, &msg.msg_control->cmsg_data,
&msg.msg_control->cmsg_len, 0, (sockaddr *)&msg.msn_name,&msg.msg_namelen);
anyone has got an idea if my way of thinking is ok here? imho, the framework
is poorly organized, so I don't find a direct way to test it for only this
purpose.
but in for example Cygwin, there is no "msg_control" in the msghdr-struct.
(/usr/include/cygwin/socket.h)
Due to absence of experience with msghdr, I have no idea if my translation
can work and I am looking for a second opinion or other ideas.
Many kind greetings and thanks in advance,
--wim | 
July 22nd, 2005, 05:51 PM
| | | | re: migrating recvmsg() to recvfrom()
Hi Group,
guess I found a solution, I'll post it right here just for the
threads-sake:
if you want to port a *nix-program that uses the recvmsg() and
sendmsg()-functions, you can migrate them by using the following code:
ssize_t fake_recvmsg(int sd, struct msghdr *msg, int flags)
{
ssize_t bytes_read;
size_t expected_recv_size;
ssize_t left2move;
char *tmp_buf;
char *tmp;
int i;
assert(msg->msg_iov);
expected_recv_size = 0;
for(i = 0; i < msg->msg_iovlen; i++)
expected_recv_size += msg->msg_iov[i].iov_len;
tmp_buf = malloc(expected_recv_size);
if(!tmp_buf)
return -1;
left2move = bytes_read = recvfrom(sd,
tmp_buf,
expected_recv_size,
flags,
(struct sockaddr *)msg->msg_name,
&msg->msg_namelen
);
for(tmp = tmp_buf, i = 0; i < msg->msg_iovlen; i++)
{
if(left2move <= 0) break;
assert(msg->msg_iov[i].iov_base);
memcpy(
msg->msg_iov[i].iov_base,
tmp,
MIN(msg->msg_iov[i].iov_len,left2move)
);
left2move -= msg->msg_iov[i].iov_len;
tmp += msg->msg_iov[i].iov_len;
}
free(tmp_buf);
return bytes_read;
}
and
ssize_t fake_sendmsg(int sd, struct msghdr *msg, int flags)
{
ssize_t bytes_send;
size_t expected_send_size;
size_t left2move;
char *tmp_buf;
char *tmp;
int i;
assert(msg->msg_iov);
expected_send_size = 0;
for(i = 0; i < msg->msg_iovlen; i++)
expected_send_size += msg->msg_iov[i].iov_len;
tmp_buf = malloc(expected_send_size);
if(!tmp_buf)
return -1;
for(tmp = tmp_buf, left2move = expected_send_size, i = 0; i <
msg->msg_iovlen; i++)
{
if(left2move <= 0) break;
assert(msg->msg_iov[i].iov_base);
memcpy(
tmp,
msg->msg_iov[i].iov_base,
MIN(msg->msg_iov[i].iov_len,left2move));
left2move -= msg->msg_iov[i].iov_len;
tmp += msg->msg_iov[i].iov_len;
}
bytes_send = sendto(sd,
tmp_buf,
expected_send_size,
flags,
(struct sockaddr *)msg->msg_name,
msg->msg_namelen
);
free(tmp_buf);
return bytes_send;
}
greetings and have a nice Sunday-evening,
--wim
-------------------------
Many thanks to Lev Walkin |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 225,720 network members.
|