Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Unix域套接字传递文件描述符-sendmsg:未连接传输终结点_C_Linux_Sockets_Unix - Fatal编程技术网

C Unix域套接字传递文件描述符-sendmsg:未连接传输终结点

C Unix域套接字传递文件描述符-sendmsg:未连接传输终结点,c,linux,sockets,unix,C,Linux,Sockets,Unix,我一直在阅读博客和这里的各种问题,因此试图了解如何使用Unix域套接字传递文件描述符。但是,我不断收到sendmsg错误-“传输端点未连接” 如果有人能帮助我理解我做错了什么,我将不胜感激 服务器: #include <stdio.h> #include <sys/socket.h> #include <sys/un.h> #include <stdlib.h> #include <unistd.h> #include <QDeb

我一直在阅读博客和这里的各种问题,因此试图了解如何使用Unix域套接字传递文件描述符。但是,我不断收到sendmsg错误-“传输端点未连接”

如果有人能帮助我理解我做错了什么,我将不胜感激

服务器:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <unistd.h>
#include <QDebug>

char *socket_path = "/.socket";

ssize_t sock_fd_write(int sock, void *buf, ssize_t buflen, int fd)
{
    ssize_t     size;
    struct msghdr   msg;
    struct iovec    iov;
    union {
        struct cmsghdr  cmsghdr;
        char        control[CMSG_SPACE(sizeof (int))];
    } cmsgu;
    struct cmsghdr  *cmsg;

    iov.iov_base = buf;
    iov.iov_len = buflen;

    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;

    if (fd != -1) {
        msg.msg_control = cmsgu.control;
        msg.msg_controllen = sizeof(cmsgu.control);

        cmsg = CMSG_FIRSTHDR(&msg);
        cmsg->cmsg_len = CMSG_LEN(sizeof (int));
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_RIGHTS;

        printf ("passing fd %d\n", fd);
        *((int *) CMSG_DATA(cmsg)) = fd;
    } else {
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
        printf ("not passing fd\n");
    }

    printf ("sendmsg: %d\n", sock);

    size = sendmsg(sock, &msg, 0);

    if (size < 0)
        perror ("sendmsg");
    return size;
}

int main(int argc, char *argv[]) {
    struct sockaddr_un addr;
    char buf[100];
    int fd,cl,rc;

    if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket error");
        exit(-1);
    }

    qDebug() << "Created Socket";

    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);

    unlink(socket_path);

    int reuse = 1;
    int err = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
    if (0 == err) {
        err = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
        if ( err == -1 ) {
            perror("bind error");
            exit(-1);
        }
    }

    qDebug() << "Bound socket: " << fd;

    if (listen(fd, 5) == -1) {
        perror("listen error");
        exit(-1);
    }

    qDebug() << "Listening";

    while (1) {

        qDebug() << "About to accept";

        if ( (cl = accept(fd, NULL, NULL)) == -1) {
            perror("accept error");
            qDebug() << "Accept error";
            continue;
        }

        while ( (rc=read(cl,buf,sizeof(buf))) > 0) {

            printf("read %u bytes: %.*s\n", rc, rc, buf);

            qDebug() << "sock_fd_write: " << fd;

            ssize_t size;
            size = sock_fd_write(fd, (void*)"1", 1, 1);
            printf ("wrote %d\n", size);

        }
        if (rc == -1) {
            perror("read");
            exit(-1);
        }
        else if (rc == 0) {
            printf("EOF\n");
            close(cl);
        }
    }


    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
char*socket_path=“/.socket”;
ssize_t sock_fd_write(int sock,void*buf,ssize_t buflen,int fd)
{
大小;
结构msghdr msg;
结构iovec iov;
联合{
结构cmsghdr-cmsghdr;
字符控制[CMSG_空间(sizeof(int))];
}cmsgu;
结构cmsghdr*cmsg;
iov.iov_base=buf;
iov.iov_len=buflen;
msg.msg_name=NULL;
msg.msg_namelen=0;
msg.msg_iov=&iov;
msg.msg_iovlen=1;
如果(fd!=-1){
msg.msg_control=cmsgu.control;
msg.msg_controllen=sizeof(cmsgu.control);
cmsg=cmsg_FIRSTHDR(&msg);
cmsg->cmsg_len=cmsg_len(sizeof(int));
cmsg->cmsg\U电平=SOL\U插座;
cmsg->cmsg\U类型=SCM\U权限;
printf(“通过fd%d\n”,fd);
*((int*)CMSG_DATA(CMSG))=fd;
}否则{
msg.msg_control=NULL;
msg.msg_controllen=0;
printf(“未通过fd\n”);
}
printf(“sendmsg:%d\n”,sock);
大小=sendmsg(sock和msg,0);
如果(尺寸<0)
perror(“sendmsg”);
返回大小;
}
int main(int argc,char*argv[]){
结构sockaddr_un addr;
char-buf[100];
int fd、cl、rc;
if((fd=socket(AF_UNIX,SOCK_STREAM,0))=-1){
perror(“套接字错误”);
出口(-1);
}

qDebug()我需要使用accept套接字“cl”而不是listen套接字“fd”。

sock\u fd\u write(fd,(void*)“1”,1,1)
。看起来您正在向
listen
套接字(
fd
)而不是
accept
套接字(
cl
)写入。谢谢-请回答下面的问题,我将接受答案并投票表决。
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <QDebug>

char *socket_path = "/.socket";

ssize_t sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd) {

    ssize_t     size;

    if (fd) {
        struct msghdr   msg;
        struct iovec    iov;
        union {
            struct cmsghdr  cmsghdr;
            char        control[CMSG_SPACE(sizeof (int))];
        } cmsgu;
        struct cmsghdr  *cmsg;

        iov.iov_base = buf;
        iov.iov_len = bufsize;

        msg.msg_name = NULL;
        msg.msg_namelen = 0;
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        msg.msg_control = cmsgu.control;
        msg.msg_controllen = sizeof(cmsgu.control);
        size = recvmsg (sock, &msg, 0);
        if (size < 0) {
            perror ("recvmsg");
            exit(1);
        }
        cmsg = CMSG_FIRSTHDR(&msg);
        if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
            if (cmsg->cmsg_level != SOL_SOCKET) {
                fprintf (stderr, "invalid cmsg_level %d\n",
                         cmsg->cmsg_level);
                exit(1);
            }
            if (cmsg->cmsg_type != SCM_RIGHTS) {
                fprintf (stderr, "invalid cmsg_type %d\n",
                         cmsg->cmsg_type);
                exit(1);
            }

            *fd = *((int *) CMSG_DATA(cmsg));
            printf ("received fd %d\n", *fd);
        } else
            *fd = -1;
    } else {
        size = read (sock, buf, bufsize);
        if (size < 0) {
            perror("read");
            exit(1);
        }
    }
    return size;
}

int main(int argc, char *argv[]) {
    struct sockaddr_un addr;
    char buf[100];
    int fd,rc;

    if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket error");
        exit(-1);
    }

    qDebug() << "Socket connected";

    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);

    if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
        perror("connect error");
        exit(-1);
    }

    qDebug() << "Socket connected";

    ssize_t size;

    int fdRead;

    while( (rc=read(STDIN_FILENO, buf, sizeof(buf))) > 0) {

        qDebug() << "About to write";

        if (write(fd, buf, rc) != rc) {

            if (rc > 0) {

                qDebug() << "Partial write";

                size = sock_fd_read(fd, buf, sizeof(buf), &fdRead);
                if (size <= 0) {
                    break;
                }
                printf("read %d\n", size);
                if (fd != -1) {
                    write(fd, "hello, world\n", 13);
                    close(fd);
                }

            }
            else {

                perror("write error");
                exit(-1);

            }

        }
    }

    return 0;

}