2 回答
TA贡献1829条经验 获得超6个赞
如果您唯一的选择是读取行直到超时,您可以在第一次读取完成后在连接上设置读取截止日期。然后,您可以拦截超时错误,并将其转换为 EOF,以便缓冲阅读器正确解释您的意图。
type timeoutReader struct {
net.Conn
once sync.Once
}
func (r *timeoutReader) Read(b []byte) (int, error) {
n, err := r.Conn.Read(b)
// Set a read deadline only after the first Read completes
r.once.Do(func() {
r.Conn.SetReadDeadline(time.Now().Add(3 * time.Second))
})
// If we got a timeout, treat it as an io.EOF so the bufio.Scanner handles
// the error as if it was the normal end of the stream.
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
return n, io.EOF
}
return n, err
}
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:15000")
if err != nil {
log.Fatal(err)
}
scanner := bufio.NewScanner(&timeoutReader{Conn: conn})
message := ""
for scanner.Scan() {
message += scanner.Text()
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
log.Println(message)
}
TA贡献1803条经验 获得超3个赞
如果条件是收到第一行后3秒超时,解决办法是收到第一行后3秒关闭socket。
var firstLineReceived bool
conn, err := net.Dial("tcp", "127.0.0.1:15000")
reader := bufio.NewReader(conn)
message := ""
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
break
}
message += line
if !firstLineReceived {
firstLineReceived = true
go func(){
time.Sleep(3*time.Second)
conn.Close()
}()
}
}
log.Println(message)
- 2 回答
- 0 关注
- 156 浏览
添加回答
举报