Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > GoLang socket长度校验

GoLang socket网络编程传输数据包时进行长度校验的方法

作者:程序员勋勋1

在GoLang socket网络编程中,为了确保数据交互的稳定性和安全性,通常会通过传输数据的长度进行校验,发送端首先发送数据长度,然后发送数据本体,接收端则根据接收到的数据长度和数据本体进行比较,以此来确认数据是否传输成功

正常来说,我们发送和接收数据时,是像下面这样的:

// 发送端
func main() {
	conn, _ := net.Dial("tcp", "127.0.0.1:8889")
	data := []byte("hello world")
	conn.Write(data)
	fmt.Println("成功发送: ", 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))
}

运行结果如下:

这样看似没问题,但实际上还是存在着一定的风险(如数据丢失、解析错误…),这时就需要在发送和接受时对数据进行校验来确保交互的稳定性和安全性。

我们通常利用传输数据的长度来进行校验,思路如下:发送端先发送数据长度len1,再发送数据本体。接收端先接收到数据长度len1,再接收到数据本体,然后将数据本体的程度与数据长度len1进行比较,若二者相等则确认数据传输成功。

上代码

// 发送端
func main() {
	conn, _ := net.Dial("tcp", "127.0.0.1:8889")
	data := []byte("hello world")
	// 发送data的长度len1
	len1 := make([]byte, len(data))
	dataLen := uint32(len(data))
	binary.BigEndian.PutUint32(len1[:4], dataLen)
	conn.Write(len1[:4])
	// 发送data本体
	conn.Write(data)
	fmt.Println("成功发送: ", 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 转为 uint32
	// 接收到 data
	data := make([]byte, 1024)
	realLen, _ = conn.Read(data[:dataLen])
	// 在这里进行校验
	if realLen != int(dataLen) {
		fmt.Println("数据在传输时出现问题")
		return
	}
	fmt.Println("成功接收: ", string(data))
}

这样,我们就在接收端初步实现了数据的校验。

众所周知,Read()函数和Write()函数都可以实际传输了多少长度(字节),所以我们可以根据这个来完善一下数据的校验。

思路:在每次传输数据(Read或Write)时,我们根据返回的传输长度进行判断。

例如:

realLen, _ := conn.Write(buf[:4])
	if realLen != 4 {
		fmt.Println("数据在传输时出现问题")
		return
	}
realLen, _ = conn.Write(data)
	if realLen != int(dataLen) {
		fmt.Println("数据在传输时出现问题")
		return
	}

在我们之前的代码中完善这个校验:

// 发送端
func main() {
	conn, _ := net.Dial("tcp", "127.0.0.1:8889")
	data := []byte("hello world")
	// 发送data的长度len1
	len1 := make([]byte, len(data))
	dataLen := uint32(len(data))
	binary.BigEndian.PutUint32(len1[:4], dataLen)
	conn.Write(len1[:4])
	// 完善校验
	if realLen != 4 {
		fmt.Println("数据在传输时出现问题")
		return
	}
	// 发送data本体
	conn.Write(data)
	// 完善校验
	if realLen != int(dataLen) {
		fmt.Println("数据在传输时出现问题")
		return
	}
	fmt.Println("成功发送: ", 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 转为 uint32
	// 完善校验
	if realLen != 4 {
		fmt.Println("数据在传输时出现问题")
		return
	}
	// 接收到 data
	data := make([]byte, 1024)
	realLen, _ = conn.Read(data[:dataLen])
	// 完善校验
		if realLen != int(dataLen) {
		fmt.Println("数据在传输时出现问题")
		return
	}
	// 在这里进行校验
	if realLen != int(dataLen) {
		fmt.Println("数据在传输时出现问题")
		return
	}
	fmt.Println("成功接收: ", string(data))
}

这样,就实现了对数据的长度的校验。

到此这篇关于GoLang socket网络编程传输数据包时如何进行长度校验的文章就介绍到这了,更多相关GoLang socket长度校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文