簡體   English   中英

去TCP讀取是非阻塞的

[英]Go TCP read is non blocking

我正在嘗試在Go中創建服務器和客戶端,我已經設法與服務器和客戶端進行通信。 但是我的問題是,在golang中讀取的TCP是非阻塞的。 我想知道的是,golang中的讀取是否可能像C中的讀取一樣被阻塞。謝謝

編輯:

這是服務器的源代碼:

func Init_tcp() *net.TCPListener {
    laddr, err := net.ResolveTCPAddr("tcp", ":4243")
    if err != nil {
            log.Fatal(err)
    }
    tcp, err := net.ListenTCP("tcp", laddr)
    if err != nil {
            log.Fatal(err)
    }
    return tcp
}

func main() {
    tcp := Init_tcp()
    conn, _ := tcp.Accept()
    data := make([]byte, 512)
    conn.SetNoDelay(false)
    for {
            conn.Read(data)
            fmt.Println(data)
    }
}

和我的客戶:

func Init_tcp() *net.TCPConn {
    laddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:4243")
    if err != nil {
            log.Fatal(err)
    }
    tcp, err := net.DialTCP("tcp", nil, laddr)
    if err != nil {
            log.Fatal(err)
    }
    return tcp
}

func main() {
   tcp := Init_tcp()
   tcp.Write([]byte("hello world"))
}

Reader可以返回部分數據。 在文檔中 ,“如果某些數據可用,但不是len(p)個字節,按常規,Read將返回可用數據,而不是等待更多數據。”

無論使用哪種語言,這都是一個問題,即使在C語言中這種情況對您來說也是如此:TCP只是提供了可以隨時寫入的字節流。 從設計上講,單次寫入可能會分解為多個數據包進行傳輸,並且沒有內置的信號向接收方說明單次寫入/消息/請求在何處結束。 應用程序必須找出自己的信號邊界方法。 這可能意味着定界符( \\n )或隱式或顯式的字節數(HTTP的Content-Length是顯式的)。

要讀取特定數量的輸入字節,您需要io.ReadAtLeastio.ReadFull 要讀取直到滿足某些任意條件,只要沒有錯誤,就應該在Read調用上循環。 (然后,您可能想對太大的輸入進行錯誤處理,以防止不良的客戶端net/textproto服務器資源。)如果要實現基於文本的協議,則應考慮使用net/textproto ,它將bufio.Reader放在前面連接,以便您可以閱讀線路。 為了限制您等待多長時間才能完成讀取(以使行為異常的客戶端無法永遠掛斷goroutine並永遠使用內存等),請查看名稱中帶有Deadlinenet函數(與Timeout相關) Error類型)。 context包有助於管理超時,期限和取消,並且在例如您要編寫一個復雜的服務器來對每個請求執行許多網絡操作的情況下特別有用。

示例代碼有一個可能不相關但重要的問題:它丟棄了ReadWrite錯誤。 這可能掩蓋了簡單的問題,並使它們很難調試。 如果考慮了部分讀取后仍遇到問題,請先檢查所有錯誤,然后再尋求更多幫助。 查看errcheck ,以確保不會發生類似這樣的錯誤。

暫無
暫無

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

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