Sockets 如何在go中找到客户端正在从tcp缓冲区读取数据

Sockets 如何在go中找到客户端正在从tcp缓冲区读取数据,sockets,go,tcp,Sockets,Go,Tcp,我开始在一个项目中使用golang相当长的时间。在我的项目中,我必须实现一个响应tcp客户端的tcp服务器。服务器必须向客户端发送大量消息。 问题是,当服务器将消息写入客户端连接时,它必须等待客户端从缓冲区读取该消息,然后发送另一条消息(服务器必须等待客户端调用reader.ReadString('\n')方法) 在我的服务器代码中,我写道: for { data := <-client.outgoing client.writer.WriteString(data + "

我开始在一个项目中使用golang相当长的时间。在我的项目中,我必须实现一个响应tcp客户端的tcp服务器。服务器必须向客户端发送大量消息。 问题是,当服务器将消息写入客户端连接时,它必须等待客户端从缓冲区读取该消息,然后发送另一条消息(服务器必须等待客户端调用
reader.ReadString('\n')
方法)

在我的服务器代码中,我写道:

for {
    data := <-client.outgoing
    client.writer.WriteString(data + "\n")
    client.writer.Flush()
}
用于{

数据:=我认为要么是作业模棱两可,要么是你误解了它并解决了问题

简单的回答是,您永远不可能仅仅通过查看TCP会话就知道客户端是否读取了消息。您必须在应用程序中实现此“协议”

这里有几个问题:

  • 从您的应用程序中,您实际上无法访问TCP正在执行的操作。您可以获得一个可以执行I/O的流

    • 对您的流的写入“成功”这一事实只意味着TCP同意尝试传输您的内容,并且有一个独立的副本。它没有说明数据是否已被接收,甚至不意味着数据已被发送
    • 您可能会发现某些机制可以窥探TCP的内部工作(例如,
      ioctl
      s、
      SIOCINQ
      SIOCOUTQ
      或各种setsockopts):这些都没有帮助
  • 即使你知道你的TCP在做什么,这也只能告诉你远程TCP在做什么。因此,如果你完全控制你的TCP,甚至看到来自对等方的确认,你仍然不知道应用程序在做什么。很可能应用程序还没有读取数据(它可能没有请求数据,TCP可能出于某种奇怪的原因将其保留在缓冲区中,调度程序可能没有安排远程进程等。)

  • 回到您的问题,要真正了解远程应用程序是否已收到您的消息,一种方法是让远程应用程序告诉您。这意味着您必须将协议重新构造为:

  • 从服务器发送内容
  • 等待来自应用程序的消息,告诉您它已收到您的资料
  • 发送更多的东西(因为从第2点你知道这样做是安全的)

  • 你不能。TCP不是这样工作的。有没有办法获得客户端TCP自由缓冲区大小?我认为你试图解决错误的问题。你能后退一步并解释你试图实现的目标(即更高级别的视图)吗?这个问题是我学校项目的一部分。也许我的观点错了,但我读了这个项目,我认为这是我必须做的。我必须重新阅读这个项目,然后如果你把TCP协议栈的级别降到足够低的水平,你可以对远程接收窗口中剩下的内容持悲观态度,基本上就是你的发送时间不阻塞。这仍然不能告诉您客户端何时实际读取消息。TCP堆栈甚至不知道应用程序“读取”消息意味着什么;它是否在正确的应用程序层收到?它是否已由客户端成功处理?这是在应用程序层执行的一个原因。