Файловые дескрипторы и сокетные соединения - PullRequest
1 голос
/ 18 августа 2010

Я пытаюсь понять, как файловые дескрипторы связаны с сокетами.Насколько я понимаю, вы слушаете определенный файловый дескриптор, как только соединение приходит, вы принимаете его, который возвращает вам другой файловый дескриптор (всего 2), и вы используете этот 2-й дескриптор для отправки / получения данных.

Странное поведение, которое я наблюдаю, заключается в том, что после подтверждения у меня есть 3 файловых дескриптора вместо двух .... и я не уверен, почему это так ....

IЯ использую lsof или / proc / pid для наблюдения за увеличением количества fd.

ps: это сокеты af_unix.

РЕДАКТИРОВАТЬ: КОД

Вот код для создания скокета.

   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 Core 13.

Причина, по которой мне нужно проверить это, я не хочу, чтобы мой процесс держался за FD;будучи со временем демоном, он может загнать систему в угол ...

Это действительно странное поведение.После закрытия принятого соединения я все еще остаюсь с двумя друзьями.то есть один для прослушивания и один призрачный fd ... Еще более странным является то, что даже если установлено 10 подключений, в конце каждого из них остается только один призрачный fd ...

Звучиткак конкретная реализация ОС ..

Ура!

Ответы [ 4 ]

2 голосов
/ 18 августа 2010

Ваш дополнительный дескриптор файла, скорее всего, связан с syslog. Системный журнал должен открыть сокет для системного журнала, чтобы сообщить о сообщениях. Если вы явно не вызываете openlog, этот сокет открывается при первом вызове syslog, и, поскольку вы не вызываете syslog, пока не получите ошибку, вы, скорее всего, наблюдаете побочные эффекты syslog. *

1 голос
/ 18 августа 2010

Самый простой способ устранения проблем такого рода - запустить приложение под утилитой strace(1).Проверьте, какие системные вызовы сделаны, каковы параметры и возвращаемые значения, и сопоставьте это с используемыми файловыми дескрипторами.

0 голосов
/ 18 августа 2010

Вы правы в том, что это два.Вы, должно быть, путаете третью с чем-то другим.

Без дополнительной информации трудно помочь.

0 голосов
/ 18 августа 2010

Больше кода, пожалуйста.

Но я предполагаю, что вы смотрите на реализацию ОС сокета.
Вероятно, он использует один файловый дескриптор для чтения, а другой - для записи (но это предположение).

Какое значение имеет для вас то, что делает ОС в /proc/pid, там нет ничего для непосредственного использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...