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

 更新时间:2024年11月04日 15:52:03   作者:程序员勋勋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长度校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 图文详解Go中的channel

    图文详解Go中的channel

    Channel是go语言内置的一个非常重要的特性,也是go并发编程的两大基石之一,下面这篇文章主要给大家介绍了关于Go中channel的相关资料,需要的朋友可以参考下
    2023-02-02
  • 详解Go strconv包

    详解Go strconv包

    Go语言中strconv包实现了基本数据类型和其字符串表示的相互转换。这篇文章主要介绍了Go strconv包的相关知识,需要的朋友可以参考下
    2020-10-10
  • Go实现替换(覆盖)文件某一行内容的示例代码

    Go实现替换(覆盖)文件某一行内容的示例代码

    本文主要介绍了Go实现替换(覆盖)文件某一行内容的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • golang结构化日志log/slog包之slog.Record的用法简介

    golang结构化日志log/slog包之slog.Record的用法简介

    这篇文章主要为大家详细介绍了golang结构化日志log/slog包中slog.Record结构体的使用方法和需要注意的点,文中的示例代码讲解详细,需要的可以学习一下
    2023-10-10
  • 深入了解Golang中的数据类型

    深入了解Golang中的数据类型

    在计算机编程中,数据类型是非常重要的一个概念。这篇文章将详细介绍 Golang中的数据类型,包括基本类型、复合类型、引用类型以及自定义类型,希望对大家有所帮助
    2023-04-04
  • Go语言中Struct与继承与匿名字段和内嵌结构体全面详解

    Go语言中Struct与继承与匿名字段和内嵌结构体全面详解

    这篇文章主要介绍了Go语言中Struct与继承与匿名字段和内嵌结构体,Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性,感兴趣的可以了解一下
    2023-04-04
  • GOLANG版的冒泡排序和快速排序分享

    GOLANG版的冒泡排序和快速排序分享

    这篇文章主要介绍了GOLANG版的冒泡排序和快速排序分享,需要的朋友可以参考下
    2015-03-03
  • 详解Go语言如何利用高阶函数写出优雅的代码

    详解Go语言如何利用高阶函数写出优雅的代码

    高阶函数(Hiher-order Function)定义为:满足下列条件之一的函数:接收一个或多个函数作为参数;返回值是一个函数。本文为大家介绍了如何利用高阶函数写出优雅的代码,希望对大家有所帮助
    2023-01-01
  • 使用go module导入本地包的方法教程详解

    使用go module导入本地包的方法教程详解

    go module 将是Go语言默认的依赖管理工具。到今天 Go1.14 版本推出之后 Go modules 功能已经被正式推荐在生产环境下使用了。本文重点给大家介绍如何使用 go module 导入本地包,感兴趣的朋友一起看看吧
    2020-03-03
  • go并发实现素数筛的代码

    go并发实现素数筛的代码

    这篇文章主要介绍了go并发实现素数筛的代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03

最新评论