为了账号安全,请及时绑定邮箱和手机立即绑定

如何从 TCP 套接字服务器读取所有数据并随后执行操作

如何从 TCP 套接字服务器读取所有数据并随后执行操作

Go
手掌心 2022-05-23 17:14:30
在花了很多时间之后。我找不到读取来自 TCP 套接字服务器的所有数据然后进行操作的方法,因为我找不到中断循环的方法。套接字服务器发送包含许多以“\n”结尾的行的文本。客户端应该能够读取所有这些行并使用所有数据发出 POST 请求,但循环总是挂起并且没有办法打破它。然后,它将继续等待更多数据,因此停止条件可能是三秒超时。我尝试了不同的解决方案(Scanner、ReadString、ReadLine、ReadAll),但它总是挂起并且循环永远不会完成。代码中的最后一行从不打印。 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 } log.Println(message)
查看完整描述

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)

}


查看完整回答
反对 回复 2022-05-23
?
繁星点点滴滴

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)


查看完整回答
反对 回复 2022-05-23
  • 2 回答
  • 0 关注
  • 156 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信