我开始在一个项目中使用 golang 相当长的时间。在我的项目中,我必须实现一个响应 tcp 客户端的 tcp 服务器。服务器必须向客户端发送大量消息。
问题是,当服务器向客户端连接写入消息时,它必须等到客户端从缓冲区读取该消息,然后再发送另一条消息(服务器必须等到客户端调用 reader.ReadString ('\n')
方法)。
在我的服务器代码中我写了:
for {
data := <-client.outgoing
client.writer.WriteString(data + "\n")
client.writer.Flush()
}
但服务器将所有消息发送给客户端,而无需等待客户端中的 ReadString。
如何让服务器等到客户端读取一条消息,然后再发送另一条消息?
最佳答案
我认为要么赋值不明确,要么你误解了它并解决了 the XY problem .
简短的回答是,您永远无法仅通过查看 TCP 对话就知道客户端是否已阅读消息。您必须在您的应用程序中实现此“协议(protocol)”。
这里有几个问题:
在您的应用程序中,您真的无法访问 TCP 正在做什么。您将获得一个可以在其上执行 I/O 的流。
- 写入您的流“成功”的事实仅意味着 TCP 已同意尝试传输您的内容并拥有独立的副本。它没有说明数据是否已收到,甚至不表示数据已发送
- 您可能会发现某些机制可以窥探 TCP 的内部工作(例如
ioctl
、SIOCINQ
、SIOCOUTQ
或各种 setsockopts):这些不会帮助
即使您知道您的 TCP 在做什么,这也只会告诉您远程 TCP 在做什么。因此,即使您完全控制了您的 TCP,甚至看到了对等方的确认,您仍然不知道应用程序在做什么。应用程序很可能还没有读取数据(它可能还没有请求数据,TCP 可能出于某些奇怪的原因将它保留在缓冲区中,调度程序可能没有调度远程进程等)
回到您的问题,真正了解远程应用程序是否收到您的消息的一种方法是让远程应用程序告诉您。这意味着您必须重组协议(protocol)以:
- 从服务器发送内容
- 等待来自应用程序的消息告诉您它已收到您的资料
- 发送更多内容(因为您从第 2 点知道这样做是安全的)
关于sockets - 如何发现客户端正在从 go 中的 tcp 缓冲区读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46895315/