在C语言Socket编程中,accept()函数返回值为0(标准输入文件描述符),这是什么意思?

3
我正在尝试创建一个使用C套接字编程接受多个客户端的服务器,但是当客户端连接时,sockfd=accept()有时会返回0(零),它是stdin文件描述符。
据我所知,文件描述符返回未使用的最小值,因此可能会返回0。但是,当我尝试在sockfd(即0)上进行侦听或将数据发送到sockfd时,它都不起作用,并且两者都返回0。
我该如何解决这个问题?
我正在使用RaspberryPi Raspbian(debian)。

4
你是否已经关闭了 STDIN_FILENO(或者 stdin)?这在将服务器程序变为守护进程时非常普遍。你能否展示一些代码,最好是一个具有“最小、完整和可验证性”的例子? - Some programmer dude
现在我再次阅读回答问题之后的问题,很明显需要一个MCVE :/ - Antti Haapala -- Слава Україні
1个回答

3
在POSIX上,函数返回的文件描述符是可用文件描述符中最小的一个。如果你关闭了STDIN_FILENO或者stdin,那么0可能会变成可用的,并且会被connect返回。
请注意,文件描述符0没有什么特别之处,它被用作标准输入只是一种约定而已;在Linux上,accept(2)手册明确使用了“非负数”的词汇,这包括它可能返回0
引用:

RETURN VALUE

成功时,这些系统调用返回一个非负整数,它是所接受套接字的描述符。出错时,返回-1,并设置errno。


你可以通过不关闭STDIN_FILENO,而是打开例如/dev/null进行读取,并将该文件描述符复制到STDIN_FILENO(为简洁起见省略了错误检查)来避免这种情况。
int fd = open("/dev/null", O_RDONLY);
dup2(fd, STDIN_FILENO);
close(fd);

(或者关闭STDIN_FILENO,然后立即打开/dev/null,但这有点晦涩):

close(STDIN_FILENO);
open("/dev/null", O_RDONLY);

我不确定你所说的“listen”的意思;已连接的TCP套接字无法被“listen”。此外,从“send”返回的“0”意味着您明确地发送了0字节;因为在出错时会返回“-1”。


谢谢Antti,不是'listen'而是'recv()',对此很抱歉。accept()返回'0'并成功显示连接,但当我尝试recv()时无法从客户端接收任何数据。 - Sandip

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接