【问题标题】:Socket communication: can send fail when receive succeeded?套接字通信:接收成功时发送失败吗?
【发布时间】:2016-03-12 05:28:21
【问题描述】:

据我了解 TCP/IP,它不能保证接收方 (B) 是否真的从发送方 (A) 收到任何数据。例如:

A: socket.write(1);
B: socket.read(); // this can fail and A wouldn't know unless B sends an ACK

我一直在想,相反的情况也可能吗?

A: socket.write(1); // can this fail while B does receive "1" without any error?
B: socket.read();

【问题讨论】:

  • 当然不能。这个问题没有意义。
  • @EJP:我担心的原因是,我看到了即使紧接着断开连接(即另一端无法接收数据)写入/发送也会成功的情况,所以我不确定在什么情况下写/发送操作可以失败。 SergeyA 的答案正是我想要的。
  • 这个问题似乎 100% 有效,我也经历过。写入套接字失败,但收到消息。大多数时候我注意到失败是由于超时或发送缓冲区中的空间不足。添加重试逻辑有助于在一定程度上摆脱它。

标签: sockets tcp-ip


【解决方案1】:

send() 调用有 4 种不同的可能结果:

  1. send() 返回等于它的第三个参数 (len) 的字节数。这意味着,消息已成功放入 TCP 堆栈,现在堆栈将尽最大努力传递它。
  2. send() 返回 -1。这意味着,有一个本地可检测的错误。例如,套接字未连接,消息太大而无法原子传递等。什么都没有发送。 errno 会有错误的实际原因。
  3. send() 返回一个非负数,不等于它的第三个参数。这意味着,send() 无法发送整个消息,而是发送了其中的一部分。最可能的原因是非阻塞 send() 调用,发送缓冲区中没有空间容纳其余部分。 errno 可能会设置为 EAGAIN (EWOULDBLOCK)。这意味着,消息的某些部分已发送,因此接收者可以看到它。
  4. 应用程序接收到 SIGPIPE 信号。这意味着,套接字在另一端被关闭,并且 SIGPIPE 没有被抑制。没有发送任何内容。

【讨论】:

  • 谢谢,您的回答让我没有任何疑问!现在真的很难想象如果发送方收到错误代码,对方将如何收到正确的数据。
猜你喜欢
  • 2015-05-12
  • 2012-06-07
  • 1970-01-01
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
  • 2013-12-21
  • 1970-01-01
  • 2010-11-14
相关资源
最近更新 更多