Tcp 如何使net.Read在golang中等待输入?

Tcp 如何使net.Read在golang中等待输入?,tcp,go,Tcp,Go,因此,我在Go中为我的电梯创建了一个服务器,并将函数“handler”作为带有TCP连接的goroutine运行。 我希望它从一个连接中读取,如果在某个时间段内没有检测到信号,我希望它返回一个错误 func handler(conn net.Conn){ conn.SetReadTimeout(5e9) for{ data := make([]byte, 512) _,err := conn.Read(data) } } 只要我有一个客户

因此,我在Go中为我的电梯创建了一个服务器,并将函数“handler”作为带有TCP连接的goroutine运行。 我希望它从一个连接中读取,如果在某个时间段内没有检测到信号,我希望它返回一个错误

func handler(conn net.Conn){
    conn.SetReadTimeout(5e9)
    for{
        data := make([]byte, 512)
        _,err := conn.Read(data)
    }
}
只要我有一个客户端通过连接发送东西,它似乎工作得很好,但只要客户端停止发送net.Read函数,它就会返回错误EOF并开始毫无延迟地循环


这可能是Read应该如何工作的,但是有人能建议另一种方法来处理这个问题,而不必在每次我想读东西时关闭和打开连接吗?

垃圾收集器(GC)可能关闭连接的一端,因为
net.Conn
从GC角度成为无法访问的对象。为了防止这种情况:在客户端停止发送后,请确保客户端连接存储在代码可以访问的变量中


另一种选择是,在程序的某个地方,您正在关闭连接的一端,而不知道它。

我认为Read正在按预期工作。听起来你想让网络像围棋中的一个频道一样工作。这在go中非常简单,只需包装网络。阅读一个正在运行的goroutine并使用select从频道中读取goroutine非常便宜,频道也是如此

例如:

ch := make(chan []byte)
eCh := make(chan error)

// Start a goroutine to read from our net connection
go func(ch chan []byte, eCh chan error) {
  for {
    // try to read the data
    data := make([]byte, 512)
    _,err := conn.Read(data)
    if err != nil {
      // send an error if it's encountered
      eCh<- err
      return
    }
    // send data if we read some.
    ch<- data
  }
}(ch, eCh)

ticker := time.Tick(time.Second)
// continuously read from the connection
for {
  select {
     // This case means we recieved data on the connection
     case data := <-ch:
       // Do something with the data
     // This case means we got an error and the goroutine has finished
     case err := <-eCh:
       // handle our error then exit for loop
       break;
     // This will timeout on the read.
     case <-ticker:
       // do nothing? this is just so we can time out if we need to.
       // you probably don't even need to have this here unless you want
       // do something specifically on the timeout.
  }
}
ch:=make(chan[]字节)
eCh:=制造(chan错误)
//启动goroutine以从网络连接读取
go func(通道[]字节,通道错误){
为了{
//尝试读取数据
数据:=生成([]字节,512)
_,err:=conn.Read(数据)
如果错误!=零{
//如果遇到错误,请发送错误

eChconn.SetReadTimeout(5e9)不是您想要的。SetReadTimeout需要的是绝对时间,而不是持续时间。请尝试指定为“time.Seconds*10”编译器会抱怨。你上面说的是,你希望连接在1970年1月1日之后的5000秒超时。因此它根本不会等待。相反,你想要的是conn.SetReadTimeout(time.Now().Add(time.seconds*10))的效果对于10秒超时。文档明确警告不要使用这种方式。另外,我认为比一秒小得多的值更合适。我认为你错了,但我认为你可能是对的。所以不要让我放弃投票。