GoLang?socket網(wǎng)絡(luò)編程傳輸數(shù)據(jù)包時(shí)進(jìn)行長度校驗(yàn)的方法
正常來說,我們發(fā)送和接收數(shù)據(jù)時(shí),是像下面這樣的:
// 發(fā)送端 func main() { conn, _ := net.Dial("tcp", "127.0.0.1:8889") data := []byte("hello world") conn.Write(data) fmt.Println("成功發(fā)送: ", string(data)) }
// 接收端 func main() { listen, _ := net.Listen("tcp", "0.0.0.0:8889") conn, _ := listen.Accept() data := make([]byte, 1024) conn.Read(data) fmt.Println("成功接收: ", string(data)) }
運(yùn)行結(jié)果如下:
這樣看似沒問題,但實(shí)際上還是存在著一定的風(fēng)險(xiǎn)(如數(shù)據(jù)丟失、解析錯(cuò)誤…),這時(shí)就需要在發(fā)送和接受時(shí)對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)來確保交互的穩(wěn)定性和安全性。
我們通常利用傳輸數(shù)據(jù)的長度來進(jìn)行校驗(yàn),思路如下:發(fā)送端先發(fā)送數(shù)據(jù)長度len1,再發(fā)送數(shù)據(jù)本體。接收端先接收到數(shù)據(jù)長度len1,再接收到數(shù)據(jù)本體,然后將數(shù)據(jù)本體的程度與數(shù)據(jù)長度len1進(jìn)行比較,若二者相等則確認(rèn)數(shù)據(jù)傳輸成功。
上代碼
// 發(fā)送端 func main() { conn, _ := net.Dial("tcp", "127.0.0.1:8889") data := []byte("hello world") // 發(fā)送data的長度len1 len1 := make([]byte, len(data)) dataLen := uint32(len(data)) binary.BigEndian.PutUint32(len1[:4], dataLen) conn.Write(len1[:4]) // 發(fā)送data本體 conn.Write(data) fmt.Println("成功發(fā)送: ", string(data)) }
// 接收端 func main() { listen, _ := net.Listen("tcp", "0.0.0.0:8889") conn, _ := listen.Accept() // 接收到 data 的長度 len1:= make([]byte, 1024) realLen, _ := conn.Read(len1[:4]) dataLen := binary.BigEndian.Uint32(len1[:4])// 將 data 的長度由 []byte 轉(zhuǎn)為 uint32 // 接收到 data data := make([]byte, 1024) realLen, _ = conn.Read(data[:dataLen]) // 在這里進(jìn)行校驗(yàn) if realLen != int(dataLen) { fmt.Println("數(shù)據(jù)在傳輸時(shí)出現(xiàn)問題") return } fmt.Println("成功接收: ", string(data)) }
這樣,我們就在接收端初步實(shí)現(xiàn)了數(shù)據(jù)的校驗(yàn)。
眾所周知,Read()函數(shù)和Write()函數(shù)都可以實(shí)際傳輸了多少長度(字節(jié)),所以我們可以根據(jù)這個(gè)來完善一下數(shù)據(jù)的校驗(yàn)。
思路:在每次傳輸數(shù)據(jù)(Read或Write)時(shí),我們根據(jù)返回的傳輸長度進(jìn)行判斷。
例如:
realLen, _ := conn.Write(buf[:4]) if realLen != 4 { fmt.Println("數(shù)據(jù)在傳輸時(shí)出現(xiàn)問題") return }
realLen, _ = conn.Write(data) if realLen != int(dataLen) { fmt.Println("數(shù)據(jù)在傳輸時(shí)出現(xiàn)問題") return }
在我們之前的代碼中完善這個(gè)校驗(yàn):
// 發(fā)送端 func main() { conn, _ := net.Dial("tcp", "127.0.0.1:8889") data := []byte("hello world") // 發(fā)送data的長度len1 len1 := make([]byte, len(data)) dataLen := uint32(len(data)) binary.BigEndian.PutUint32(len1[:4], dataLen) conn.Write(len1[:4]) // 完善校驗(yàn) if realLen != 4 { fmt.Println("數(shù)據(jù)在傳輸時(shí)出現(xiàn)問題") return } // 發(fā)送data本體 conn.Write(data) // 完善校驗(yàn) if realLen != int(dataLen) { fmt.Println("數(shù)據(jù)在傳輸時(shí)出現(xiàn)問題") return } fmt.Println("成功發(fā)送: ", string(data)) }
// 接收端 func main() { listen, _ := net.Listen("tcp", "0.0.0.0:8889") conn, _ := listen.Accept() // 接收到 data 的長度 len1:= make([]byte, 1024) realLen, _ := conn.Read(len1[:4]) dataLen := binary.BigEndian.Uint32(len1[:4])// 將 data 的長度由 []byte 轉(zhuǎn)為 uint32 // 完善校驗(yàn) if realLen != 4 { fmt.Println("數(shù)據(jù)在傳輸時(shí)出現(xiàn)問題") return } // 接收到 data data := make([]byte, 1024) realLen, _ = conn.Read(data[:dataLen]) // 完善校驗(yàn) if realLen != int(dataLen) { fmt.Println("數(shù)據(jù)在傳輸時(shí)出現(xiàn)問題") return } // 在這里進(jìn)行校驗(yàn) if realLen != int(dataLen) { fmt.Println("數(shù)據(jù)在傳輸時(shí)出現(xiàn)問題") return } fmt.Println("成功接收: ", string(data)) }
這樣,就實(shí)現(xiàn)了對(duì)數(shù)據(jù)的長度的校驗(yàn)。
到此這篇關(guān)于GoLang socket網(wǎng)絡(luò)編程傳輸數(shù)據(jù)包時(shí)如何進(jìn)行長度校驗(yàn)的文章就介紹到這了,更多相關(guān)GoLang socket長度校驗(yàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在golang中使用Sync.WaitGroup解決等待的問題
這篇文章主要介紹了在golang中使用Sync.WaitGroup解決等待的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04關(guān)于升級(jí)go1.18的goland問題詳解
作為一個(gè)go語言程序員,覺得自己有義務(wù)為go新手開一條更簡單便捷的上手之路,下面這篇文章主要給大家介紹了關(guān)于升級(jí)go1.18的goland問題的相關(guān)資料,需要的朋友可以參考下2022-11-11golang interface{}類型轉(zhuǎn)換的實(shí)現(xiàn)示例
在Go語言中,類型轉(zhuǎn)換可以通過斷言、顯式、隱式和強(qiáng)制四種方式實(shí)現(xiàn),針對(duì)interface{}類型轉(zhuǎn)換為float32或float64,需要使用type斷言或reflect包處理,感興趣的可以了解一下2024-10-10Go語言操作數(shù)據(jù)庫及其常規(guī)操作的示例代碼
這篇文章主要介紹了Go語言操作數(shù)據(jù)庫及其常規(guī)操作的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Go中的new()和make()函數(shù)區(qū)別及底層原理詳解
這篇文章主要為大家介紹了Go中的new()和make()函數(shù)區(qū)別及底層原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09服務(wù)器端Go程序?qū)﹂L短鏈接的處理及運(yùn)行參數(shù)的保存
這篇文章主要介紹了服務(wù)器端Go程序?qū)﹂L短鏈接的處理及運(yùn)行參數(shù)的保存,這里針對(duì)使用Go語言編寫的Socket服務(wù)器進(jìn)行實(shí)例說明,需要的朋友可以參考下2016-03-03intelliJ?idea安裝go開發(fā)環(huán)境并搭建go項(xiàng)目(打包)全過程
最近在配置idea開發(fā)go語言時(shí)碰到很多問題,所以這里給大家總結(jié)下,這篇文章主要給大家介紹了關(guān)于intelliJ?idea安裝go開發(fā)環(huán)境并搭建go項(xiàng)目(打包)的相關(guān)資料,需要的朋友可以參考下2023-10-10