多次使用 socketpair 函数的文件描述符时出现“错误的文件描述符”错误

Posted

技术标签:

【中文标题】多次使用 socketpair 函数的文件描述符时出现“错误的文件描述符”错误【英文标题】:"Bad file descriptor" error, when using file descriptors of the socketpair function more than once 【发布时间】:2011-03-28 09:09:49 【问题描述】:

以下代码使用套接字对从子进程向其父进程发送消息。

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

#define MESSAGE "Hello"

int main()
 
    char message[100];
    int i, pidFork, sockets[2];

    /*
     *Trying to use a single socketpair function call
     *
     *if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) 
     *   perror("Creating socketpair");
     *   exit(-1);
     *
     */

    for(i=0; i<2; i++)  

        if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) 
            perror("Creating socketpair");
            exit(-1);
        

        printf("i: %d\n", i);
        pidFork = fork();
        if (pidFork == -1) 
            perror("Creating child process");
            exit(-1);
        

        else if (pidFork != 0)  //Parent
            close(sockets[0]);
            if(read(sockets[1], message, strlen(MESSAGE)) == -1) 
                perror("Reading data");
                exit(-1);
            
            printf("Data: %s\n\n", message);
            close(sockets[1]);
        

        else  //Child
            close(sockets[1]);
            if(write(sockets[0], MESSAGE, strlen(MESSAGE)) == -1) 
                perror("Writing data");
                exit(-1);
            
            close(sockets[0]);
            exit(0);
        
    
    return 0;

首先,我尝试在进入 for 循环之前通过对 socketpair 函数的一次调用来获取套接字对的文件描述符,例如注释行所示,但这仅适用于第一次迭代,从第二次迭代开始我得到一个“错误的文件描述符错误”,我让它工作的方式是在 for 循环中移动 socketpair 函数调用,但是第一种方法在使用管道时对我有用。

所以我想知道为什么会这样,我犯错了吗? 或者这是两种 IPC 机制之间的区别吗?

谢谢

更新: pipe 和 socketpair 的文件描述符没有区别。我认为它正在使用管道,因为我的完整程序的另一部分出现错误。 接受的答案解决了我的问题。

【问题讨论】:

【参考方案1】:

您正在关闭父级和子级中 socketpair 的两端。

一般来说,每个子进程使用一对套接字或管道。

【讨论】:

感谢您的回答和建议。如果我删除对 close 函数的所有调用,它会起作用,我使用了这种方法,因为这是我在大多数示例中发现的:对子进程和父进程中的两个文件描述符的 close 调用。此外,当使用管道时,即使对 close 函数的所有调用也能正常工作,只是为了好奇:你知道为什么吗? @Mkfnx:当你用“pipe()”替换“socketpair()”系统调用时,你确认它有效吗?我同意 Larsmans 的观点,这很奇怪……难道没有调用“dup()”或“dup2()”吗?再见! @Giuseppe 我刚刚上传了一个我认为我的问题所在的示例案例。但是现在我重新检查了我的原始代码,发现我正在修改程序其他部分的消息并且我没有显示错误消息,这让我认为它正在工作,当它不是......对不起为此:(。所以拉尔斯曼的回答是正确的:D谢谢! @Mkfnx:感谢您的澄清。再见!

以上是关于多次使用 socketpair 函数的文件描述符时出现“错误的文件描述符”错误的主要内容,如果未能解决你的问题,请参考以下文章

Android Framework实战开发-socketpair介绍及它在android系统源码使用分析

Android Framework实战开发-socketpair介绍及它在android系统源码使用分析

Android Framework实战开发-socketpair介绍及它在android系统源码使用分析

socketpair和pipe的区别

在 Python 中使用管道文件描述符时如何检查 EOF?

使用 socketpair 进行双向通信:挂起子进程的读取输出