Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > migrating recvmsg() to recvfrom()

Reply
Thread Tools

migrating recvmsg() to recvfrom()

 
 
Wim Deprez
Guest
Posts: n/a
 
      07-21-2004
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



 
Reply With Quote
 
 
 
 
Wim Deprez
Guest
Posts: n/a
 
      07-25-2004
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Migrating from Mozilla to Firefox Daniel Prince Firefox 1 12-11-2004 04:47 AM
migrating thunderbird to a new installation - how? sam Firefox 2 11-29-2004 01:33 AM
migrating passwords? Ken Wald Firefox 0 10-31-2004 03:53 AM
Help migrating to thunderbird from Mozilla eliot Firefox 2 08-27-2004 07:01 PM
Thunderbird file sharing & migrating/remoting data-mine@else-wh.ere Firefox 0 04-30-2004 03:50 AM



Advertisments