文件描述符和套接字连接

时间:2010-08-18 13:45:36

标签: c++ c sockets unix network-programming

我试图了解文件描述符与套接字的关系。根据我的理解,你监听一个特定的文件描述符,一旦连接进来,你接受它,它返回另一个文件描述符(总共2个),你使用这个第二个描述符发送/ recv数据。

我观察到的奇怪行为是,在接受之后,我有3个文件描述符而不是两个....我不知道为什么会这样......

我要么使用lsof或/ proc / pid来观察fd数量的增加。

ps:这些是af_unix套接字。

编辑:代码

以下是创建scoket的代码。

   int s, s2,  len;
    socklen_t t;
    struct sockaddr_un local, remote;

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
    {
            syslog(LOG_ERR,"Failed to create a socket");
            exit(1);
    }
    int flags =  fcntl(s, F_GETFD);
    if (flags == -1)
    {
            syslog(LOG_ERR,"Failed to get socket flags");
            exit(1);
    }

    flags |= FD_CLOEXEC;

    if (fcntl(s, F_SETFD, flags) == -1)
    {
            syslog(LOG_ERR,"Failed to set socket flags");
            exit(1);
    }

    local.sun_family = AF_UNIX;
    strcpy(local.sun_path, SOCK_PATH.c_str());

    unlink(local.sun_path);
    len = strlen(local.sun_path) + sizeof(local.sun_family);

    if (bind(s, (struct sockaddr *)&local, len) == -1)
    {
            syslog(LOG_ERR,"Failed to bind socket");
            exit(1);
    }


    if (listen(s, 5) == -1)
    {
            syslog(LOG_ERR,"Failed to listen at socket");
            exit(1);
    }

接受连接的代码

    while (1)
    {
            stat =0;
            execReturn=0;
            t = len;
            read_fds = master;
            if (select(fdmax+1, &read_fds, NULL, NULL, &tv) != -1)
            {
                    if(FD_ISSET(s,&read_fds))
                    {
                            //Accept new connection
                            //fork child -> fork grand child
                            //child will return value back

                            if ((s2 = accept(s, (struct sockaddr*)&remote, &t)) == -1)
                            {
                                    syslog(LOG_ERR,"Failed to acceptconnection  at socket");
                                    exit(1);
                            }

我正在逐步完成gdb并且在接受之后,fd变为3.操作系统是Fedora核心13。

我需要验证这一点的原因是我不希望我的进程持有FD的;由于随着时间的推移成为守护进程,它可能会将系统带入一个角落......

这似乎很奇怪。在关闭接受的连接后,我仍然留下了两个fd。 即一个用于监听和一个鬼fd ......更奇怪的是,即使建立了10个连接,只有一个鬼fd在所有关闭结束时仍然存在....

听起来像操作系统特定的实现..

干杯!

4 个答案:

答案 0 :(得分:2)

您的额外文件描述符很可能与syslog相关。 Syslog必须打开syslogd的套接字来报告消息。除非您明确调用openlog,否则在第一次调用syslog时会打开此套接字,并且由于在出现错误之前未调用syslog,因此您很可能会观察syslog的副作用。

答案 1 :(得分:1)

调试此类问题的最简单方法是在strace(1)实用程序下运行您的应用。检查进行了哪些系统调用,参数和返回值是什么,并将其与使用的文件描述符相关联。

答案 2 :(得分:0)

请更多代码。

但我猜你正在考虑套接字的操作系统实现 它可能使用一个文件描述符进行读取而另一个用于写入(但这是猜测)。

操作系统在/proc/pid中所做的事情对您来说有什么关系。那里的内容并不适合您直接使用。

答案 3 :(得分:0)

你是对的,因为它是两个。你必须把第三个与其他东西混淆。

没有更多信息,很难提供帮助。