GoLang?socket網(wǎng)絡(luò)編程傳輸數(shù)據(jù)包時進(jìn)行長度校驗(yàn)的方法
正常來說,我們發(fā)送和接收數(shù)據(jù)時,是像下面這樣的:
// 發(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ù)丟失、解析錯誤…),這時就需要在發(fā)送和接受時對數(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ù)在傳輸時出現(xiàn)問題")
return
}
fmt.Println("成功接收: ", string(data))
}這樣,我們就在接收端初步實(shí)現(xiàn)了數(shù)據(jù)的校驗(yàn)。
眾所周知,Read()函數(shù)和Write()函數(shù)都可以實(shí)際傳輸了多少長度(字節(jié)),所以我們可以根據(jù)這個來完善一下數(shù)據(jù)的校驗(yàn)。
思路:在每次傳輸數(shù)據(jù)(Read或Write)時,我們根據(jù)返回的傳輸長度進(jìn)行判斷。
例如:
realLen, _ := conn.Write(buf[:4])
if realLen != 4 {
fmt.Println("數(shù)據(jù)在傳輸時出現(xiàn)問題")
return
}realLen, _ = conn.Write(data)
if realLen != int(dataLen) {
fmt.Println("數(shù)據(jù)在傳輸時出現(xiàn)問題")
return
}在我們之前的代碼中完善這個校驗(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ù)在傳輸時出現(xiàn)問題")
return
}
// 發(fā)送data本體
conn.Write(data)
// 完善校驗(yàn)
if realLen != int(dataLen) {
fmt.Println("數(shù)據(jù)在傳輸時出現(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ù)在傳輸時出現(xiàn)問題")
return
}
// 接收到 data
data := make([]byte, 1024)
realLen, _ = conn.Read(data[:dataLen])
// 完善校驗(yàn)
if realLen != int(dataLen) {
fmt.Println("數(shù)據(jù)在傳輸時出現(xiàn)問題")
return
}
// 在這里進(jìn)行校驗(yàn)
if realLen != int(dataLen) {
fmt.Println("數(shù)據(jù)在傳輸時出現(xiàn)問題")
return
}
fmt.Println("成功接收: ", string(data))
}這樣,就實(shí)現(xiàn)了對數(shù)據(jù)的長度的校驗(yàn)。
到此這篇關(guān)于GoLang socket網(wǎng)絡(luò)編程傳輸數(shù)據(jù)包時如何進(jìn)行長度校驗(yàn)的文章就介紹到這了,更多相關(guān)GoLang socket長度校驗(yàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在golang中使用Sync.WaitGroup解決等待的問題
這篇文章主要介紹了在golang中使用Sync.WaitGroup解決等待的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04
golang interface{}類型轉(zhuǎn)換的實(shí)現(xiàn)示例
在Go語言中,類型轉(zhuǎn)換可以通過斷言、顯式、隱式和強(qiáng)制四種方式實(shí)現(xiàn),針對interface{}類型轉(zhuǎn)換為float32或float64,需要使用type斷言或reflect包處理,感興趣的可以了解一下2024-10-10
Go語言操作數(shù)據(jù)庫及其常規(guī)操作的示例代碼
這篇文章主要介紹了Go語言操作數(shù)據(jù)庫及其常規(guī)操作的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
Go中的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ù)的保存,這里針對使用Go語言編寫的Socket服務(wù)器進(jìn)行實(shí)例說明,需要的朋友可以參考下2016-03-03
intelliJ?idea安裝go開發(fā)環(huán)境并搭建go項(xiàng)目(打包)全過程
最近在配置idea開發(fā)go語言時碰到很多問題,所以這里給大家總結(jié)下,這篇文章主要給大家介紹了關(guān)于intelliJ?idea安裝go開發(fā)環(huán)境并搭建go項(xiàng)目(打包)的相關(guān)資料,需要的朋友可以參考下2023-10-10

