在尝试学习套接字编程时,我看到了以下代码:
int sock;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
我翻阅了man页面并发现socket返回一个文件描述符。我尝试在互联网和其他类似的问题中搜索,但我无法理解文件描述符到底是什么。如果有人可以用简单的语言解释文件描述符,那就太棒了。
在尝试学习套接字编程时,我看到了以下代码:
int sock;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
我翻阅了man页面并发现socket返回一个文件描述符。我尝试在互联网和其他类似的问题中搜索,但我无法理解文件描述符到底是什么。如果有人可以用简单的语言解释文件描述符,那就太棒了。
有两个相关的对象:文件描述符和文件描述。人们经常混淆这两者并认为它们是相同的。
文件描述符是应用程序中的整数,它指向内核中的文件描述。
文件描述是内核中维护打开文件状态(当前位置、阻塞/非阻塞等)的结构。在Linux中,文件描述是struct file
。
open()
函数将建立文件和文件描述符之间的连接。它将创建一个打开的文件描述符,该描述符引用文件和文件描述符引用该打开的文件描述符。文件描述符由其他 I/O 函数用于引用该文件。路径参数指向命名文件的路径名。
open()
函数将为命名文件返回一个文件描述符,该文件描述符是当前未打开该进程的最低文件描述符。打开的文件描述符是新的,因此文件描述符不与系统中的任何其他进程共享。
dup
会为相同的描述符创建一个新的描述符,而open
不会这样做。 - Maxim Egorushkin以及可能的其他模式。它还索引到第三个称为inode表的表中,该表描述实际底层文件。
/proc/<pid>
目录中。这里保存了与进程相关的所有数据。此外,在进程启动时,内核会为进程分配3个文件描述符,用于与称为stdin
、stdout
和stderr
的3个数据流进行通信。0
、1
和2
。ls -l /proc/<pid>/fd/
,您将看到在那里创建了一个附加的FD,其ID为4
(如果程序使用了其他资源,则也可能是其他数字)。我认为文件描述符是指向由内核维护的不透明文件对象(间接、高级)指针。
通常,当您处理库维护的对象时,会向库传递指向您不应自行引用和操作的对象的指针。
对于内核对象来说,不仅仅是因为您不应该自己操纵它们 - 因为它们存在于不可访问的不同地址空间中,所以您根本无法操纵它们。并且因为它们存在于不同的地址空间中,指针不会成为指向它们的有意义的方式。
您需要一个令牌或句柄,内核将在内部将其解析为在内核地址空间中有意义的指针。文件描述符是这样的整数形式令牌。
对于内核:
your_process_id + your_file_descriptor => kernels_file_object_pointer