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长度校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 在golang中使用Sync.WaitGroup解决等待的问题

    在golang中使用Sync.WaitGroup解决等待的问题

    这篇文章主要介绍了在golang中使用Sync.WaitGroup解决等待的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • go语言time.After()的作用

    go语言time.After()的作用

    time.After 是 Go 语言中的一个函数,用于返回一个定时器通道,该通道在指定时间后发送当前时间,这个功能常用于超时控制和延迟执行,本文就来详细的介绍一下,感兴趣的可以了解学习
    2024-10-10
  • 关于升级go1.18的goland问题详解

    关于升级go1.18的goland问题详解

    作为一个go语言程序员,觉得自己有义务为go新手开一条更简单便捷的上手之路,下面这篇文章主要给大家介绍了关于升级go1.18的goland问题的相关资料,需要的朋友可以参考下
    2022-11-11
  • golang interface{}类型转换的实现示例

    golang interface{}类型转换的实现示例

    在Go语言中,类型转换可以通过断言、显式、隐式和强制四种方式实现,针对interface{}类型转换为float32或float64,需要使用type断言或reflect包处理,感兴趣的可以了解一下
    2024-10-10
  • Go语言操作数据库及其常规操作的示例代码

    Go语言操作数据库及其常规操作的示例代码

    这篇文章主要介绍了Go语言操作数据库及其常规操作的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Go中的new()和make()函数区别及底层原理详解

    Go中的new()和make()函数区别及底层原理详解

    这篇文章主要为大家介绍了Go中的new()和make()函数区别及底层原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • golang 字符串切片去重实例

    golang 字符串切片去重实例

    这篇文章主要介绍了golang 字符串切片去重实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 服务器端Go程序对长短链接的处理及运行参数的保存

    服务器端Go程序对长短链接的处理及运行参数的保存

    这篇文章主要介绍了服务器端Go程序对长短链接的处理及运行参数的保存,这里针对使用Go语言编写的Socket服务器进行实例说明,需要的朋友可以参考下
    2016-03-03
  • intelliJ idea安装go开发环境并搭建go项目(打包)全过程

    intelliJ idea安装go开发环境并搭建go项目(打包)全过程

    最近在配置idea开发go语言时碰到很多问题,所以这里给大家总结下,这篇文章主要给大家介绍了关于intelliJ idea安装go开发环境并搭建go项目(打包)的相关资料,需要的朋友可以参考下
    2023-10-10
  • 深入了解Go语言中sync.Pool的使用

    深入了解Go语言中sync.Pool的使用

    本文将介绍 Go 语言中的 sync.Pool并发原语,包括sync.Pool的基本使用方法、使用注意事项等的内容,对我们了解Go语言有一定的帮助,需要的可以参考一下
    2023-04-04

最新评论