簡體   English   中英

如何在客戶端通過TCP連接發送的一條消息中讀取所有數據而不會在Go中阻塞?

[英]How can I read all data in one message a client sends over TCP connection without blocking in Go?

我正在Go中實現一個procotol的服務器。 在此協議中,客戶端連接到服務器並可以發送一堆命令,並在發送每個命令后期望服務器的響應。 命令消息的格式為: COMMAND <BODY_LENGTH>\\r\\n BODY\\r\\n ,其中BODY_LENGTH是任意的,並在命令行上指定。

我解析命令的方式是:從net.Conn讀取前幾個字節,解析命令和主體長度,並以另一種讀取方式讀取整個主體,處理消息,發送響應,然后循環以等待下一個連接上的命令消息:

func handler(c net.Conn) {
    defer c.Close()
    for {
        msg := make([]byte, 1024)

        n, err := c.Read(msg)
        cmd, bodyLength = parseCommand(msg)
        // read the body of body length here
        if err == io.EOF {
            fmt.Printf("Client has closed the connection")
            break
        } 

        response := handleCommand(cmd, body)
        n, err := c.Write(response)
        if err != nil {
            fmt.Printf("ERROR: write\n")
            fmt.Print(err)
        }
        fmt.Printf("SERVER: sent %v bytes\n", n)
    }
}

我假設(在此上不清楚Go文檔) net.Conn.Read()在等待來自客戶端的下一條消息時阻塞,並且僅在客戶端關閉連接時才返回io.EOF。 如果我錯了,請糾正我。

如果命令格式正確,則一切正常。 但是,如果命令格式錯誤,並且第一行沒有正文長度,我希望我仍然可以閱讀其余消息,將其丟棄,然后等待下一條可能有效的消息。 問題是,如果我不知道期望的數據長度,那么我可能會啟動一個read(),如果我剛剛讀取了最后一個字節,它將阻塞。

如何在不知道其長度的情況下讀取整個消息(緩沖的所有內容)? 還是我必須關閉連接,並告訴客戶端為下一個命令啟動新連接?

  • TCP中沒有消息。
  • 無法保證單個send()發送的所有字節都會一起到達,或者不能全部放入接收器的套接字接收緩沖區。
  • 因此,不可能實現您的目標。

這也沒有意義。 在整個命令到達之前,您什么也做不了,並且您肯定會在命令之間阻塞。 在接收命令期間阻塞不會進一步造成傷害。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM