首页 文章

使用CLOSE_WAIT套接字写入时避免使用Go中的数据转换

提问于
浏览
1
  • 用netcat -l启动侦听客户端

  • go程序用net.DialTCP向所述客户端打开一个conn .

  • 杀死netcat

  • 在go程序中,使用[]字节执行conn.Write() - >它运行正常,没有错误!

  • 需要另一个conn.Write来获取错误:断开的管道

第一次写入是数据丢失发生的,我想避免 . 如果我只收到错误,我知道我可以保留数据并稍后再试 . 我见过https://stackoverflow.com/a/15071574/2757887,这是一个非常类似的情况,解释似乎适用于此,但它仍然没有解释如何处理该问题,如果我需要实现的tcp协议只进行单向通信 .

我用wireshark嗅到了流量,当我杀死netcat时,我可以看到它将FIN发送到go程序,go程序用ACK回复 . 出于某种原因,go程序没有立即回复它自己的FIN - 而且我很好奇为什么会这样,它可能对我的问题有帮助 - 但可能有一个很好的理由 .

无论哪种方式,从"connection termination"部分@ http://en.wikipedia.org/wiki/Transmission_Control_Protocol,我得出结论,此时套接字处于CLOSE_WAIT状态,我也用"netstat -np"确认,它显示套接字在杀死netstat后从ESTABLISHED转到CLOSE_WAIT .

看看wireshark,第一个conn.write会产生一个包含push和ack字段的数据包,当然还有我的有效负载 . 这是写得很好的写作 .

那么以前属于netstat的旧套接字发送RST,这确保一旦我尝试写入go(第二次写入)它就会失败 .

所以我的问题是:

A)为什么我不能在第一次写入时出错?如果套接字收到FIN并且处于CLOSE_WAIT状态,为什么Go让我写入套接字并告诉我一切正常?
B)有什么方法可以检查Go是否套接字是在CLOSE_WAIT?如果是这样,我可以为此目的考虑它关闭而不是写 .

谢谢,迪特

1 回答

  • 3

    从根本上说,成功的 write 只会告诉您数据已排队等待发送到另一端 . 如果您需要确保另一端获取该数据,即使连接关闭或出现错误,您也必须存储数据副本,直到另一端为您提供应用程序级别确认 .

相关问题