在C语言中调用socket函数会返回一个整型的文件描述符(file descriptor),它是一个非负整数,用来标识和引用这个新创建的socket。这个描述符在UNIX/Linux等操作系统中被广泛用于对文件、管道、网络连接等资源的引用。socket描述符的含义和底层实现原理:
描述符的含义
- 操作系统内核会为每个进程维护一个文件描述符表,记录了该进程打开的所有文件、socket等资源。
- 描述符就是文件描述符表的索引,可以通过它来访问对应的资源,是资源的一个引用或者句柄。
- 常见的标准输入stdin、标准输出stdout、标准错误stderr的描述符分别为0、1、2,其他资源的描述符则从3开始依次递增。
- socket描述符则是该socket在该进程的文件描述符表中的索引,通过它可以对这个socket进行读写、设置选项等操作。
描述符的底层实现
- 内核会对整个操作系统维护一个系统级的全局文件表(open file table),记录了系统中所有打开的文件、socket等资源。
- 每个进程有自己独立的文件描述符表,记录了该进程访问的资源在全局文件表中的索引。
- 当调用socket函数创建一个新的socket时,内核会在全局文件表中创建一项,并返回该项的索引。
- 内核会在该进程的文件描述符表中也创建一项,记录这个全局索引,这个索引就是返回的socket描述符。
- 进程通过socket描述符访问socket时,内核会通过文件描述符表找到对应的全局文件表索引,从而访问到对应的socket资源。
- 多个进程可以共享同一个socket资源,它们在自己的文件描述符表中有不同的索引,但都指向全局文件表中同一项。
socket描述符的特点
- socket描述符与文件描述符的性质类似,可以用read/write等文件IO函数对其进行读写。
- socket描述符被创建时属于当前进程,默认不能在进程间传递,但可以通过一些特殊手段实现传递,如UNIX Domain Socket。
- socket描述符可以用于I/O多路复用机制如select/poll/epoll模型,以实现高效的网络事件通知。
- socket描述符在进程退出时会被内核自动关闭并释放,也可以用close函数显式关闭。
socket描述符是内核赋予用户进程访问socket资源的一个引用或句柄,通过文件描述符表和全局文件表实现,是用户进程进行socket通信的基础。