gpt4 book ai didi

c - 当非阻塞 send() 仅传输部分数据时,我们可以假设它会在下一次调用时返回 EWOULDBLOCK 吗?

转载 作者:IT王子 更新时间:2023-10-29 00:24:44 25 4
gpt4 key购买 nike

非阻塞套接字的手册页中详细记录了两种情况:

  • 如果 send() 返回与传输缓冲区相同的长度,整个传输 成功完成,套接字可能会或可能不会处于返回 EAGAIN/EWOULDBLOCK 的状态,下一次调用 > 0 个字节要传输。
  • 如果 send() 返回 -1 并且 errno 是 EAGAIN/EWOULDBLOCK,没有传输 完成,程序需要等到套接字准备好接收更多数据(epoll 情况下为 EPOLLOUT ).

没有记录非阻塞套接字的是:

  • 如果 send() 返回一个小于缓冲区大小的正值。

假设 send() 会在多一个字节的数据上返回 EAGAIN/EWOULDBLOCK 是否安全?或者非阻塞程序是否应该尝试再发送一次 () 以获得最终的 EAGAIN/EWOULDBLOCK?如果套接字实际上不处于“会阻止”状态以响应它的出现,我担心将 EPOLLOUT 观察器放在套接字上。

显然,后一种策略(再次尝试获得结论)具有明确定义的行为,但它更加冗长并且会影响性​​能。

最佳答案

调用 send具有三种可能的结果:

  1. 发送缓冲区中至少有一个字节可用 →发送 成功并返回接受的字节数(可能少于您要求的字节数)。
  2. 在您调用 send 时,发送缓冲区已满
    →如果套接字阻塞,发送阻塞
    →如果套接字是非阻塞的,send 失败并返回 EWOULDBLOCK/EAGAIN
  3. 发生错误(例如,用户拔下网线,连接被对端重置)→发送失败并出现另一个错误

如果 send 接受的字节数小于您要求的数量,那么这意味着发送缓冲区现在已满。然而,对于任何 future 对 send 的调用,这纯粹是间接的,并且是非权威的。
send 返回的信息只是您调用 send 时当前状态的“快照”。当 send 返回或您再次调用 send 时,此信息可能已经过时。当您的程序在 send 中时,网卡可能会在网络上发送数据报,或者在一纳秒之后,或者在任何其他时间——没有办法知道。您会知道下一次调用何时成功(或何时失败)。

换句话说,这暗示下一次调用send会返回EWOULDBLOCK/EAGAIN (或者如果套接字不是非阻塞的会阻塞)。尝试直到您所谓的“获得决定性的 EWOULDBLOCK”是正确的做法。

关于c - 当非阻塞 send() 仅传输部分数据时,我们可以假设它会在下一次调用时返回 EWOULDBLOCK 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19391208/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com