在尝试学习套接字编程时,我看到了以下代码:
int sock;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
我浏览了手册页,发现socket返回了一个文件描述符。我试过在这里搜索互联网和其他类似的问题,但我无法理解文件描述符到底是什么。我必须在两天内完成我的套接字编程课程。因此,如果有人能用简单的语言解释文件描述符,那就太棒了。
答案 0 :(得分:3)
有两个相关对象:文件描述符和文件描述。人们常常把这两者混为一谈,认为它们是一样的。
文件描述符是应用程序中的一个整数,它引用内核中的文件 description 。
文件 description 是内核中维护打开文件状态(当前位置,阻塞/非阻塞等)的结构。在Linux文件中, descripion 是struct file
。
open()
函数应在文件和文件描述符之间建立连接。它应创建一个打开文件 description ,它引用一个文件和一个文件 descriptor ,它引用该打开的文件 description 。其他I / O函数使用文件描述符来引用该文件。 path参数指向命名文件的路径名。
open()
函数应返回指定文件的文件描述符,该文件描述符是当前未为该进程打开的最低文件描述符。打开的文件描述是新的,因此文件描述符不应与系统中的任何其他进程共享。
答案 1 :(得分:1)
我认为文件描述符是(间接的,更高级别的)指针到内核维护的不透明文件对象。
通常,当你处理由库维护的对象时,你会传递给你不应该自行取消引用和操纵的对象的库指针。
对于内核对象,这不仅仅是因为你不应该自己操纵它们 - 你实际上不能这样做,因为它们生活在一个完全不可访问的不同地址空间中。因为它们生活在不同的地址空间中,指针不是一种有意义的引用它们的方式。
您需要一个令牌或句柄,内核将在内部解析为在内核地址空间中有意义的指针。文件描述符是整数形式的这种标记。
对于内核:
your_process_id + your_file_descriptor => kernels_file_object_pointer
(如果给定的文件描述符可能无法解析为给定进程的文件对象指针,则会出现 EBADF 错误)
答案 2 :(得分:1)
文件描述符不过是到文件的映射。您也可以说这些是指向该进程正在使用的文件的指针。
FD只是用作处理资源指针的整数值。
每当进程启动时,正在运行的进程的条目都会添加到/proc/<pid>
目录中。在此保留与流程相关的所有数据。同样,在进程启动时,内核会为进程分配3个文件描述符,以便与称为stdin
,stdout
和stderr
的3个数据流进行通信。
linux内核使用一种算法来始终创建具有最小可能整数值的FD,因此这些数据流被映射为数字0
,1
和2
。
比方说,在您的代码中,您打开了一个文件以进行读取或写入。这意味着流程需要访问资源,并且必须为此新资源创建映射/指针。
为此,内核会在您的代码打开文件后立即自动创建FD。
如果运行ls -l /proc/<pid>/fd/
,您将在此处创建一个ID为4
的附加FD(如果程序使用了其他资源,也可以是其他数字)
答案 3 :(得分:0)
在Unix / Linux操作系统中,文件描述符是一个抽象指示符(句柄),用于访问文件或其他IO(输入/输出)资源,例如管道或网络套接字。 通常,文件描述符索引到由Linux / Unix OS中的内核维护的每进程文件描述符表,该表又进行索引 进入由所有进程打开的系统范围的文件表,称为文件表。 此表记录用于打开文件或其他资源的“模式” 用于以下操作(还有更多操作)
可能还有其他模式。 它还索引到第三个名为inode表的表,该表描述了实际的底层文件。