重用监听套接字文件描述符的问题

Issue with the reuse of listen socket file descriptor

我正在使用预分叉概念。

当我在服务器上建立套接字时,返回的文件描述符值为7。我知道它会为文件描述符分配一个可用的数字。

当我让同一个子进程接受同一个套接字上的新连接时,它不会 accept() 连接。

但是当我将文件描述符的值重置为 7 时,它开始接受连接。

我没有找到背后的原因。任何人都可以对此有所了解。

我的代码与此类似

for (;;)
{
    int session_fd=accept(server_fd,0,0);
    if (session_fd==-1)
    {
        if (errno==EINTR) continue;
        die("failed to accept connection (errno=%d)",errno);

    }
    handle_session(session_fd);
    close(session_fd);
    server_fd = 7;

}

When I do some read and write operations, the value of file descriptor goes on increasing.

这没有意义,读取或写入应该在系统返回句柄的同一个套接字上执行。

So I am just curious to know about the significance of value of socket file descriptor.

没有意义,它是一个进程特定的句柄,用整数表示,通常每次打开时它增加1 and/or 创建一个新套接字等

我要冒险,假设你的代码看起来像 like this,你在其中绑定 server_fd,然后派生一个子节点来处理每个连接。

如果是这样,值 7 没有任何意义。碰巧在你程序的那个阶段,较低的数字已经在使用中。如果您在调用 listen 之前打开了一些其他文件或套接字,server_fd 会有不同的数字。

套接字只是它的编号,所以当您 reset the value of the file descriptor 时,您是从原始的绑定套接字读取数据,而不是 accept 调用产生的新套接字。我怀疑你不想在同一个套接字上监听两次,尽管我从未尝试过。

if (listen(server_fd,SOMAXCONN)) {
    die("failed to listen for connections (errno=%d)",errno);
}

for (;;) {
    int session_fd=accept(server_fd,0,0);
    if (session_fd==-1) {
        if (errno==EINTR) continue;
        die("failed to accept connection (errno=%d)",errno);
    }
    pid_t pid=fork();
    if (pid==-1) {
        die("failed to create child process (errno=%d)",errno);
    } else if (pid==0) {
        close(server_fd);
        handle_session(session_fd);
        close(session_fd);
        _exit(0);
    } else {
        close(session_fd);
    }
}

抱歉打扰大家了。我找到了 session_fd 值变化的问题背后的原因。

session_fd 是一个全局变量。由于这是一个巨大的遗留代码,我不知道 session_fd 的值被其他套接字更改了。

感谢大家提供意见:)