<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ### 為什么會出現粘包 主要原因就是tcp數據傳遞模式是流模式,在保持長連接的時候可以進行多次的收和發 1. 由Nagle算法造成的發送端的粘包:Nagle算法是一種改善網絡傳輸效率的算法。簡單來說就是當我們提交一段數據給TCP發送時,TCP并不立刻發送此段數據,而是等待一小段時間看看在等待期間是否還有要發送的數據,若有則會一次把這兩段數據發送出去。 2. 接收端接收不及時造成的接收端粘包:TCP會把接收到的數據存在自己的緩沖區中,然后通知應用層取數據。當應用層由于某些原因不能及時的把TCP的數據取出來,就會造成TCP緩沖區中存放了幾段數據。 ### 解決辦法 出現”粘包”的關鍵在于接收方不確定將要傳輸的數據包的大小,因此我們可以對數據包進行封包和拆包的操作。 封包:封包就是給一段數據加上包頭,這樣一來數據包就分為包頭和包體兩部分內容了(過濾非法包時封包會加入”包尾”內容)。包頭部分的長度是固定的,并且它存儲了包體的長度,根據包頭長度固定以及包頭中含有包體長度的變量就能正確的拆分出一個完整的數據包 編解碼協議: ~~~ // Encode 將消息編碼 func Encode(message string) ([]byte, error) { // 讀取消息的長度,轉換成int32類型(占4個字節) var length = int32(len(message)) var pkg = new(bytes.Buffer) // 寫入消息頭 err := binary.Write(pkg, binary.LittleEndian, length) if err != nil { return nil, err } // 寫入消息實體 err = binary.Write(pkg, binary.LittleEndian, []byte(message)) if err != nil { return nil, err } return pkg.Bytes(), nil } // Decode 解碼消息 func Decode(reader *bufio.Reader) (string, error) { // 讀取消息的長度 lengthByte, _ := reader.Peek(4) // 讀取前4個字節的數據 lengthBuff := bytes.NewBuffer(lengthByte) var length int32 err := binary.Read(lengthBuff, binary.LittleEndian, &length) if err != nil { return "", err } // Buffered返回緩沖中現有的可讀取的字節數。 if int32(reader.Buffered()) < length+4 { return "", err } // 讀取真正的消息數據 pack := make([]byte, int(4+length)) _, err = reader.Read(pack) if err != nil { return "", err } return string(pack[4:]), nil } ~~~ 服務端代碼如下: ~~~ // socket_stick/server2/main.go func process(conn net.Conn) { defer conn.Close() reader := bufio.NewReader(conn) for { msg, err := proto.Decode(reader) if err == io.EOF { return } if err != nil { fmt.Println("decode msg failed, err:", err) return } fmt.Println("收到client發來的數據:", msg) } } func main() { listen, err := net.Listen("tcp", "127.0.0.1:30000") if err != nil { fmt.Println("listen failed, err:", err) return } defer listen.Close() for { conn, err := listen.Accept() if err != nil { fmt.Println("accept failed, err:", err) continue } go process(conn) } } ~~~ 客戶端代碼如下: ~~~ // socket_stick/client2/main.go func main() { conn, err := net.Dial("tcp", "127.0.0.1:30000") if err != nil { fmt.Println("dial failed, err", err) return } defer conn.Close() for i := 0; i < 20; i++ { msg := `Hello, Hello. How are you?` data, err := proto.Encode(msg) if err != nil { fmt.Println("encode msg failed, err:", err) return } conn.Write(data) } } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看