【问题标题】:Does disconnecting from TCP socket after sending message guarantees deliver?发送消息保证交付后断开与 TCP 套接字的连接吗?
【发布时间】:2017-12-26 23:01:41
【问题描述】:

我找不到太多这方面的信息,但我有一个简单的代码序列,例如:

// does it wait on Write() until successful handshake or attempt failure
// or just continue on straight away?
net.conn.Write(buffer[1:60])
conn.Close()

这是否保证在调用Close 之前交付给客户端/服务器?还是会在消息发送后调用 Close ,如果握手太慢而无法及时完成,可能会在握手期间关闭连接?

【问题讨论】:

  • 也许您可以更清楚地了解保证的含义。 TCP 尽最大努力传递消息,但如果出现网络问题,它就无法解决。
  • 我想这取决于实现,但至少在标准情况下,关闭套接字(在建立连接之后)应该首先尝试在缓冲区中传递数据。
  • @JamesKPolk 我的意思是在握手完成或失败之前,代码是否仍然在 Write() 上而不去 Close() ?或者它是否写入/发送然后运行 ​​Close() 而不管结果如何,这意味着它可以在尚未完成来自客户端的确认时关闭?
  • @Radu 很高兴知道它会尝试发送缓冲区,但你知道他们在哪里提到过吗?
  • Write() 是一个阻塞调用,它返回已写入的bytes 的编号和可选的error(如果有)more info here

标签: sockets go tcp


【解决方案1】:

这是否保证在调用Close 之前交付给客户端/服务器?

没有。

或者在消息发送后会调用Close

写入和关闭都排队等待异步执行。

如果握手太慢而无法及时完成,可能会在握手期间关闭连接?

Close 将排队关闭连接。如果关闭握手时间过长,连接将被重置。

【讨论】:

  • 那么在您想要关闭但需要知道消息是否成功发送或“成功”发送失败的情况下,处理这种情况的安全方法是什么,以便您知道关闭连接或先尝试再次发送?
  • 对等应用程序必须告诉你。
  • Write 至少是阻塞调用,而不是异步调用。我不知道Close,但不知何故我怀疑它的异步,因为我在 Go 中知道的每个 I/O 调用都是阻塞的; Go 使一切同步,如果您选择这样做,则由您在 goroutine 中异步运行它。在某些操作系统下,操作系统可能会异步运行它,而进程对此没有发言权,但这肯定不是普遍正确的。
  • 这在文档中没有明确说明,但是,超时如何工作的解释强烈暗示了这一点;如果写入/读取超时,WriteRead返回错误;如果他们异步写入/读取,这是不可能的。
  • @Adrian 1. write() 等于 send(),由于存在套接字发送缓冲区,它异步操作close(() 也是如此,无论您是否知道,这仍然是正确的:否则没有理由存在具有正超时的 SO_LINGER。我建议你看看这个。 2. 我没有说异步读取工作。 3. 如果 this 写入超时,则没有“超时如何工作的解释”说明写入会返回错误。
【解决方案2】:

没有什么可以“保证交付”(如果连接的另一端刚刚崩溃怎么办?)。但是Write是一个阻塞调用,如果你检查返回的error值,你至少可以在调用Close之前知道写入是否成功。

【讨论】:

  • 您可以知道写入是否成功将您的数据传输到套接字发送缓冲区。仅此而已。
猜你喜欢
  • 1970-01-01
  • 2022-09-28
  • 1970-01-01
  • 2015-02-07
  • 1970-01-01
  • 2015-01-09
  • 2019-03-31
  • 2014-11-20
  • 1970-01-01
相关资源
最近更新 更多