小编Yu *_*ing的帖子

为什么要考虑缓冲区而不是线路?fgets() 可以一次读取多行吗?

最近我在读《Unix网络编程第一卷》。在3.9节中,图3.18最后两段说了,这里我引用一下:

...但是我们的建议是从黄油而不是行的角度来思考,编写代码来读取数据的黄油,如果需要一行,请检查缓冲区以查看它是否包含该行。

在下一段中,作者给出了一个更具体的例子,这里我引用一下:

...我们将在第 6.3 节中看到。像 select 这样的系统函数仍然不知道 readline 的内部缓冲区,因此粗心编写的程序很容易发现自己在 select 中等待已经接收并存储在 readline 缓冲区中的数据。

在6.5节中,实际的问题是“stdio和select()的混合”,这将使程序“容易出错”,这里我引用这本书。但如何呢?

我知道作者稍后在同一节中给出了答案,根据我对本书的理解,这是因为 select() 隐藏了数据,因此 select() 无法知道已读取的数据是消耗与否。

答案确实存在,但这里的第一个问题是我真的很难得到它,我无法想象它会对程序造成什么损害,也许我需要一个遇到这个问题的演示程序来帮助我理解它。

还是在第 6.5 节中,作者试图进一步解释这个问题,我在这里引用:

...考虑当标准输入有几行输入可用时的情况。select 将导致第 20 行的代码使用 fgets 读取输入,然后将可用行读入 stdio 使用的缓冲区中。但是,fgets 只返回一行,并将所有剩余数据留在 stdio 缓冲区中......

上面提到的“第20行”是:

if (Fgets(sendline, MAXLINE, fp) == NULL)
Run Code Online (Sandbox Code Playgroud)

其中 sendline 是 char 数组,fp 是指向 FILE 的指针。我查看了 Fgets 的详细实现,它只是用一些额外的错误处理逻辑包装了 fgets() ,仅此而已。

这是我的第二个问题,fgets 如何设法,在这里我再次引用,读取可用的?我的意思是,我查阅了 fgets 的手册页,它说 fgets 通常在第一个换行符处停止。这不是意味着 fgets 只会读取一行吗?更具体地说,如果我在终端中输入一行并按 Enter 键,则 fgets 会读取这一行。我再次执行此操作,然后 fgets 读取下一个新行,并且该点一次一行。

感谢您耐心阅读所有描述,并期待您的答复。

c++ unix network-programming

3
推荐指数
1
解决办法
125
查看次数

标签 统计

c++ ×1

network-programming ×1

unix ×1