使用C TCP套接字,可以'发送'返回零吗?

Adr*_*ian 16 c sockets tcp return-value send

send使用TCP套接字时,C 函数是否可能返回零?手册页只是说它将返回发送的字节数,但我不确定它是否只会在无法发送任何数据时返回-1.

pax*_*blo 17

我很确定,虽然记忆深藏在时间的迷雾中,但我之前已经看到它返回零,在大规模数据传输的情况下,另一端没有跟上.

从内存来看,在这种情况下,远程TCP堆栈缓冲区已经填满,堆栈已通知本地端,它将延迟直到某个空间被清除并且本地缓冲区也已填满.

此时,它在技术上并不是一个错误(因此没有返回-1),但是本地堆栈不能接受任何数据.

我现在还不完全确定是这种情况,因为目前的Posix标准似乎表明它会在这种情况下简单地阻止(或者如果设置为非阻塞则会失败).

但是,我怀疑这是一个没有实际意义的问题.你确实有可能返回少于你请求发送的字节,因此你应该有代码来处理它.

而且,由于处理"零字节"的逻辑处理几乎与处理"零字节"相同,因此您可以假设它可以返回零.

  • @paxdiablo:我认为你的解释是对的.如果套接字处于阻塞模式,并且接收器报告其接收缓冲区已满,则send()只是阻塞,直到它可以再次发送数据(或发生致命错误/超时).如果套接字处于非阻塞模式,则它立即返回-1并且错误代码为EWOULDBLOCK.根据我的经验,返回值0总是表示0字节传递给send(),或者另一方正常关闭套接字(或至少称为shutdown(0)). (8认同)
  • @RemyLebeau我同意.send()的行为不依赖于实现,与此答案中断言的内容相反.几十年前,它由BSD和Posix定义.但是,您对"另一方已优雅关闭"的评论不正确.如果你继续发送,那将导致ECONNRESET,而不是返回零码. (7认同)
  • 我该如何处理?我的程序应该继续尝试发送还是应该失败? (2认同)
  • 您应该继续尝试发送,因为它不是错误条件.如果它没有恢复,那么你最终会收到一个错误.这就是你应该指出失败的地方.您可能想要考虑的一件事是在重试之前在零返回代码之后引入延迟.这将为临时问题提供更多时间.您可以遵循许多策略. (2认同)

Jer*_*ner 5

好吧,总是存在这样的情况:您传入零作为要发送的字节数......在这种情况下,“返回发送的字节数”将表明它应该返回零字节。

无论如何,最好正确处理返回零的情况;它不会造成伤害,而且可能会有所帮助。