sendmsg and recvmsg

#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>


ssize_t readn(int fd, void *buf, size_t nbytes)
{
ssize_t nleft = 0;
ssize_t nread = 0;
char  *ptmp = NULL;


ptmp = (char*)buf;
nleft = nbytes;


while(nleft > 0)
{
if( (nread = read(fd, ptmp, nleft)) < 0)
{
if(errno == EINTR)
{
nread = 0;
}
else
{
return -1;
}
}
else if(nread == 0)
{
break;
}


nleft -= nread;
ptmp += nread;
}


return (nbytes - nleft);
}


ssize_t writen(int fd, const void *buf, size_t nbytes)
{
size_t nleft = 0;
ssize_t nwritten = 0;
const char  *ptmp = NULL;


ptmp = (char*)buf;
nleft = nbytes;


while(nleft > 0)
{
if( (nwritten = write(fd, ptmp, nleft)) <= 0)
{
if(errno == EINTR)
{
nwritten = 0;
}
else
{
return -1;
}
}


nleft -= nwritten;
ptmp += nwritten;
}


return nbytes;
}


int recv_time(int sock, void *buf, int bufsize, struct timeval *tv)
{
    fd_set fds;
int res;


// wait for some data to be read
do {
errno = 0;
FD_ZERO(&fds);
FD_SET(sock, &fds);
res = select(sock + 1, &fds, NULL, NULL, tv);
} while (res < 0 && errno == EINTR);
if (res < 0) return 0;
if (res == 0) {
// timeout
errno = ETIMEDOUT;  // select was succesfull, errno is now 0
return 0;
}


// socket ready, read the data
do {
errno = 0;
res = recv(sock, (char*)buf, bufsize, 0);
} while (res < 0 && errno == EINTR);
if (res < 0) return 0;
if (res == 0) {
// orderly shutdown
errno = ENOTCONN;
return 0;
}


return res;
}


int send_msg(int sock, channel_msg *data, int size)
{
    msghdr  msg;


    if(data->fd == -1)
    {
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
    }
    else
    {
        union
        {
            struct cmsghdr cm;
            char space[CMSG_SPACE(sizeof(int))];
        }cmsg;
        memset(&cmsg, 0, sizeof(cmsg));


        cmsg.cm.cmsg_level = SOL_SOCKET;
        cmsg.cm.cmsg_type = SCM_RIGHTS;
        cmsg.cm.cmsg_len = CMSG_LEN(sizeof(int));


        msg.msg_control = (cmsghdr*)&cmsg;
        msg.msg_controllen = sizeof(cmsg);
        *(int*)CMSG_DATA(&cmsg.cm) = data->fd;
    }


    iovec iov[1];
    iov[0].iov_base = data;
    iov[0].iov_len = size;


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


    msg.msg_name = NULL;
    msg.msg_namelen = 0;


    ssize_t ret ;
    ret = sendmsg(sock, &msg, 0);


    return ret;
}
int recv_msg(int sock, channel_msg *data, int size)
{
    msghdr msg;
    iovec iov[1];
    iov[0].iov_base = data;
    iov[0].iov_len = size;


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


    msg.msg_name = NULL;
    msg.msg_namelen = 0;


    union
    {
        struct cmsghdr cm;
        char space[CMSG_SPACE(sizeof(int))];
    }cmsg;
    memset(&cmsg, 0, sizeof(cmsg));


    msg.msg_control = (cmsghdr*)&cmsg;
    msg.msg_controllen = sizeof(cmsg);


    ssize_t ret;
    ret = recvmsg(sock, &msg, 0);
    if(ret < 0)
    {
        return -1;
    }
    if(ret == 0)
    {
        return 0;
    }


    if(data->command == CMD_FD)
    {
        int fd = *(int*)CMSG_DATA(&cmsg.cm);
        data->fd = fd;
    }
    else
    {
        data->fd = -1;
    }


     return ret;


    return 0;
}

你可能感兴趣的:(sendmsg and recvmsg)