【问题标题】:Level-triggered or edge-triggered?电平触发还是边沿触发?
【发布时间】:2016-10-03 20:04:47
【问题描述】:

我有一个服务器应用程序,它侦听一个端口,接受 (TCP) 对等连接,然后为每个套接字接受它

1)reads(不超过30字节数据)

2) sends (1 字节确认)

3) reads(不超过 2K)

4) sends (1 字节确认)

5)closes(连接)

我在我的应用程序中使用epoll 循环。我希望 epoll_wait 返回(带有 EPOLLIN 标志的事件列表)仅当所有数据都从对等方到达时,以便我可以通过单个 read/recv 调用读取数组。如果某个套接字 fd 上没有收到所有数据,我不希望 epoll 将此 fd 添加到事件列表中。

据我了解,epoll 的电平触发模式和边缘触发模式之间的差异可以使用边缘触发的epoll 来实现,该模式具有非阻塞套接字和有限状态以跟踪步骤。

如果我对边缘触发选项有误,请纠正我。任何想法?

【问题讨论】:

    标签: c linux sockets epoll


    【解决方案1】:

    epoll_wait 报告套接字准备好读取之前,似乎无法设置传入套接字缓冲区中可用的最小字节数。

    man socket(7):

    SO_RCVLOWAT 和 SO_SNDLOWAT

    指定缓冲区中的最小字节数,直到套接字层将数据传递给协议(SO_SNDLOWAT)或用户接收(SO_RCVLOWAT)。这两个值被初始化为 1。SO_SNDLOWAT 在 Linux 上不可更改(setsockopt(2) 失败并出现错误 ENOPROTOOPT)。 SO_RCVLOWAT 仅在 Linux 2.4 之后才可更改。 select(2) 和 poll(2) 系统调用目前不遵守 Linux 上的 SO_RCVLOWAT 设置,并且即使只有一个字节的数据可用,也会将套接字标记为可读。 随后从套接字读取将阻塞直到 SO_RCVLOWAT 字节可用。

    除非手册页已过期。

    【讨论】:

    • 你的意思是不管电平触发还是边沿触发模式,都有可能我只读取,比如说,1K(部分读取),然后我将不得不读取其余的数据,说 1K?
    • @fade2black 正是这样,当至少有 1 个字节可用时,他们报告套接字准备好读取。
    • 它是 TCP,一个八位字节/字节流协议。它不能传输超过一个字节的消息。
    • 所以,在边缘触发模式下,到达的数据只被通知一次,我必须阅读它,因为下次 epoll_wait 不会通知我。触发水平怎么样?每次 epoll_wait 返回时它都会通知我相同的数据(直到下一部分数据到达),对吧?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    • 2021-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多