由于我最近刚开始学习 libev,因此io_watcher
我不太了解a 中的可读/可写概念。据我所知,linux系统编程中有一个参数:
O_ASYNC
当指定的文件变得可读或可写时,将生成一个信号(默认为 SIGIO)。此标志仅适用于终端和套接字,不适用于常规文件。
那么,由于普通文件不会为可读/可写而烦恼,那么在套接字编程中可读/可写究竟意味着什么?内核采取了什么措施来确定套接字文件描述符是否可读?
考虑到一切皆文件的理念,是否每个具有不同描述符编号的套接字描述符实际上都指向同一个文件?如果是这样,我可以认为可读/可写问题是由同步引起的吗?
好吧,看来我问了一个愚蠢的问题。我真正的意思是套接字和常规文件都通过文件描述符进行读写,那么为什么套接字描述符有可读/可写的概念而常规文件没有。由于 EJP 告诉我这是因为缓冲区和每个描述符都有自己的一对缓冲区,这是我的结论:可读/可写的概念是针对缓冲区的,如果缓冲区为空,则它不可读,而它已满,则不可写。可读和可写与同步无关,并且由于常规文件没有缓冲区,因此它始终是可读和可写的。
还有更多的问题:在说接收缓冲区时,这个缓冲区不是同一个东西int recv(SOCKET socket, char FAR* buf, int len, int flags);
,对吧?
这个问题在Unix Network Programming, Volume 1: The Sockets Networking API (3rd Edition) [W. Richard Stevens、Bill Fenner、Andrew M. Rudoff](请参阅此处。我将添加一些小的编辑以增强可读性):
\n\n\n\n\n描述符在什么条件下准备就绪?
\n\n\n\n
select
[...]\n 导致套接字返回“就绪”的条件是:1 . 如果满足以下四个条件中的任何一个,则套接字已准备好读取:
\n\n\n
\n\n- 套接字接收缓冲区中数据的字节数大于或等于套接字接收缓冲区低水位标记的当前大小。套接字上的读取操作不会阻塞,并将返回一个大于 0 的值(即已准备好读取的数据)。[...]
\n- 连接的读取部分已关闭(即已接收到 FIN 的 TCP 连接)。套接字上的读取操作不会阻塞,并且\n 将返回 0(即 EOF)。
\n- 该套接字是侦听套接字,并且已完成的连接数不为零。[...]
\n- 套接字错误正在等待\n。套接字上的读取操作不会阻塞,并且会返回一个错误 (\xe2\x80\x931),并
\nerrno
设置为特定的错误条件。[...]2 . 如果满足以下四个条件中的任何一个,则套接字已准备好写入:
\n\n\n
\n\n- 套接字发送缓冲区中可用空间的字节数大于或等于套接字发送缓冲区低水位线的当前大小,并且:(i) 套接字已连接,或者 (ii) ) 套接字不需要连接(例如,UDP)。这意味着,如果我们将套接字设置为非阻塞,则写入操作将不会阻塞,并且将返回正值(例如,传输层接受的字节数)。[...]
\n- 连接的写入部分已关闭。套接字上的 write\n 操作将生成
\nSIGPIPE
.- 使用非阻塞连接的套接字已完成连接,或者连接失败。
\n- 套接字错误正在等待处理。套接字上的写入操作不会阻塞,并且会返回一个错误 (\xe2\x80\x931),并
\nerrno
设置为\n 特定的错误条件。[...]3 . 如果套接字有带外数据或套接字仍处于带外标记,则套接字有一个待处理的异常条件。
\n\n[笔记:]
\n\n\n
\n\n \n- \n
我们对“可读”和“可写”的定义直接取自 TCPv2 第 530\xe2\x80\x93531 页上的\n 内核
soreadable
和sowriteable
宏。\n 同样,我们对“异常条件”的定义套接字来自soo_select
这些相同页面上的函数。- \n
请注意,当套接字上发生错误时,它会被标记为可读可写
select
。- \n
接收和发送低水位标记的目的是让应用程序能够控制在 select 返回可读或可写状态之前必须有多少数据可用于读取或有多少空间必须可用于写入。例如,如果我们知道除非存在至少 64 字节的数据,否则我们的应用程序没有任何生产力可做,那么我们可以将接收低水位标记设置为 64,以防止 select 在准备就绪的字节数少于 64 字节时唤醒我们。阅读。
- 只要 UDP 套接字的发送低水位标记小于发送缓冲区大小(这始终是默认关系),UDP 套接字就始终可写,因为不需要连接。
\n
同一本书中的相关阅读:TCP套接字发送缓冲区和UDP套接字(伪)发送缓冲区
\n可读意味着套接字接收缓冲区中存在数据或 FIN。
可写意味着套接字发送缓冲区中有可用空间。
文件没有套接字发送或接收缓冲区。
考虑一切都是文件的哲学
那是什么哲学?
每个具有不同描述符编号的套接字描述符实际上都指向同一个文件吗?
什么文件?为什么他们会指向相同的东西?问题没有意义。
我对一件事感到困惑:创建套接字时,描述符实际上指向套接字的接收和发送缓冲区
它“指向”很多东西:源地址、目标地址、源端口、目标点、一对缓冲区、一组计数器和计时器……
该文件不代表网络硬件。
不存在“代表网络硬件的文件”这样的东西,除非您正在谈论 中的设备驱动程序条目/dev/...
,这几乎不相关。TCP 套接字是连接的端点。它特定于该连接、TCP、源和目标地址和端口,...