如何在bufio.ReadBytes()上设置超时时间?

huangapple go评论66阅读模式
英文:

how to set timeout on bufio.ReadBytes()

问题

我正在编写一段代码,用于从网络中读取数据并设置超时。最初我写了这段代码(为简化起见,省略了错误检查):

func read_msg(conn net.Conn, ch chan []byte) {
    b := bufio.NewReader(conn)
    msg,_ := b.ReadBytes(byte('\n'))
    ch <- msg
    close(ch)
}

func main() {
    ln,_ := net.Listen("tcp", ":12345")
    conn,_ := ln.Accept()
    for {
        ch := make(chan []byte)
        go read_msg(conn,ch)
        select {
        case msg := <-ch:
            fmt.Println("message received: ", msg)
        case <-time.After(time.Duration(1)*time.Second):
            fmt.Println("timeout")
        }
    }
}

当超时发生时,goroutine 会保持活动状态,等待 bufio.ReadBytes()。有没有办法在 bufio 上设置超时呢?

英文:

I am writing a code, which reads data from network with timeouts. Initially I wrote this (much simplified skipped error checks too)

func read_msg(conn net.Conn, ch chan []byte) {
    b := bufio.NewReader(conn)
    msg,_ := b.ReadBytes(byte(&#39;\n&#39;))
    ch &lt;- msg
    close(ch)
}

func main() {
    ln,_ := net.Listen(&quot;tcp&quot;, &quot;:12345&quot;)
    conn,_ := ln.Accept()
    for {
        ch := make(chan []byte)
        go read_msg(conn,ch)
        select {
        case msg := &lt;-ch:
            fmt.Println(&quot;message received: &quot;, msg)
        case &lt;-time.After(time.Duration(1)*time.Second):
            fmt.Println(&quot;timeout&quot;)
        }
    }
}

When the timeout happens, the goroutine stays active, waiting on the bufio.ReadBytes(). Is there anyway to set a timeout on the bufio itself?

答案1

得分: 3

不,bufio包没有这个功能(你可以在这里阅读文档)。

更合适的解决方案是使用net.Conn值的SetReadDeadline方法。

	// 截止时间是一个绝对时间,在此之后,I/O操作将失败而不是阻塞。截止时间适用于所有未来和挂起的I/O操作,而不仅仅是紧接着的Read或Write调用。
 ...
 	// SetReadDeadline设置未来Read调用和任何当前阻塞的Read调用的截止时间。
	// t的零值表示Read不会超时。

例如:

conn.SetReadDeadline(time.Now().Add(time.Second))
英文:

No, bufio does not have this feature (you can read the docs here).

The more appropriate solution is to use the SetReadDeadline method of the net.Conn value.

	// A deadline is an absolute time after which I/O operations
	// fail instead of blocking. The deadline applies to all future
	// and pending I/O, not just the immediately following call to
	// Read or Write.
 ...
 	// SetReadDeadline sets the deadline for future Read calls
	// and any currently-blocked Read call.
	// A zero value for t means Read will not time out.

For example:

conn.SetReadDeadline(time.Now().Add(time.Second))

huangapple
  • 本文由 发表于 2022年5月29日 07:38:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/72419951.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定