[英]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(),如果我剛剛讀取了最后一個字節,它將阻塞。
如何在不知道其長度的情況下讀取整個消息(緩沖的所有內容)? 還是我必須關閉連接,並告訴客戶端為下一個命令啟動新連接?
send()
發送的所有字節都會一起到達,或者不能全部放入接收器的套接字接收緩沖區。 這也沒有意義。 在整個命令到達之前,您什么也做不了,並且您肯定會在命令之間阻塞。 在接收命令期間阻塞不會進一步造成傷害。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.