6

由于我是最近学习 libev 的新手,所以io_watcher我不太了解 a 中的可读/可写概念。据我所知,linux系统编程中有一个参数:

O_ASYNC

当指定文件变得可读或可写时,将生成一个信号(默认为 SIGIO)。此标志仅适用于终端和套接字,不适用于常规文件。

那么,既然常规文件不会打扰可读/可写,那么可读/可写在套接字编程中的真正含义是什么?内核采取了哪些措施来确定套接字文件描述符是否可读?

考虑到一切都是文件的理念,每个具有不同描述符编号的套接字描述符实际上都指向同一个文件吗?如果是这样,我可以认为可读/可写问题是由同步引起的吗?

好吧,看来我问了一个愚蠢的问题。我真正的意思是套接字和常规文件都通过文件描述符读写,所以为什么套接字描述符有一个可读/可写的概念,而普通文件却没有。由于 EJP 告诉我这是因为缓冲区和每个描述符都有自己的缓冲区对,所以我的结论是:可读/可写概念是针对缓冲区的,如果缓冲区为空,则不可读,而缓冲区已满,则不可写。可读可写与同步无关,并且由于常规文件没有缓冲区,因此它始终是可读写的。

还有更多的问题:当说接收缓冲区时,这个缓冲区不是同一个东西int recv(SOCKET socket, char FAR* buf, int len, int flags);,对吧?

4

2 回答 2

4

这个问题在Unix Network Programming, Volume 1: The Sockets Networking API (3rd Edition) [W. Richard Stevens、Bill Fenner、Andrew M. Rudoff]在这里查看。我将添加一些小的编辑以增强可读性):

描述符在什么条件下准备就绪?

[...]导致select套接字返回“就绪”的条件[是]:

1 . 如果以下四个条件中的任何一个为真,则套接字已准备好读取:

  • 套接字接收缓冲区中的数据字节数大于或等于套接字接收缓冲区的低水位标记的当前大小。对套接字的读取操作不会阻塞,并且会返回一个大于 0 的值(即准备好读取的数据)。[...]
  • 连接的读取部分关闭(即,已收到 FIN 的 TCP 连接)。对套接字的读操作不会阻塞,将返回 0(即 EOF)。
  • 该套接字是一个侦听套接字,并且已完成的连接数非零。[...]
  • 套接字错误未决。套接字上的读取操作不会阻塞,并将返回错误 (–1) 并errno设置为特定的错误条件。[...]

2 . 如果以下四个条件中的任何一个为真,则套接字已准备好写入:

  • 套接字发送缓冲区中可用空间的字节数大于或等于套接字发送缓冲区的低水位标记的当前大小,并且:(i) 套接字已连接,或 (ii) 套接字未连接不需要连接(例如,UDP)。这意味着如果我们将套接字设置为非阻塞,写入操作将不会阻塞并且会返回一个正值(例如,传输层接受的字节数)。[...]
  • 连接的写入部分关闭。对套接字的写操作将生成SIGPIPE.
  • 使用非阻塞连接的套接字已完成连接,或连接失败。
  • 套接字错误未决。套接字上的写操作不会阻塞,并将返回错误 (–1),并errno设置为特定的错误条件。[...]

3 . 如果套接字存在带外数据或套接字仍处于带外标记处,则套接字具有待处理的异常条件。

[笔记:]

  • 我们对“可读”和“可写”的定义直接取自TCPv2 第 530-531 页上的内核soreadable和宏。sowriteable同样,我们对套接字“异常条件”的定义来自soo_select这些相同页面上的函数。

  • 请注意,当套接字上发生错误时,它会被标记为可读可写select

  • 接收和发送低水位标记的目的是让应用程序控制在选择返回可读或可写状态之前必须有多少数据可供读取或有多少空间可供写入。例如,如果我们知道除非存在至少 64 字节的数据,否则我们的应用程序无事可做,我们可以将接收低水位标记设置为 64,以防止在少于 64 字节的数据准备好时 select 唤醒我们。阅读。

  • 只要 UDP 套接字的发送低水位标记小于发送缓冲区大小(这应该始终是默认关系),UDP 套接字始终是可写的,因为不需要连接。

在此处输入图像描述

相关阅读,来自同一本书:TCP socket send buffer and UDP socket (pseudo) send buffer

于 2019-04-23T09:28:46.137 回答
1

可读意味着套接字接收缓冲区中存在数据或 FIN。

可写意味着套接字发送缓冲区中有可用空间。

文件没有套接字发送或接收缓冲区。

考虑一切即文件的理念

那是什么哲学?

每个具有不同描述符编号的套接字描述符实际上都指向同一个文件吗?

什么文件?为什么他们会指向相同的东西?问题没有意义。

我对一件事感到困惑:创建套接字时,描述符实际上指向套接字的接收和发送缓冲区

它“指向”很多东西:源地址、目标地址、源端口、目标点、一对缓冲区、一组计数器和定时器……

不是文件代表网络硬件。

没有“文件代表[ing]网络硬件”之类的东西,除非你在谈论设备驱动程序条目/dev/...,这几乎不相关。TCP 套接字是连接的端点。它特定于该连接、TCP、源和目标地址和端口,......

于 2015-07-09T10:32:19.127 回答