conn.Read(buf)读取客户端发送的数据不符合预期

之类if判断无法通过,但是fmtprint输出看着又没啥错误

func handleConnection(conn net.Conn) {
	defer conn.Close() // 函数返回前关闭连接

	for {
		buf := make([]byte, 1024) // 创建一个大小为1024字节的缓冲区
		_, err := conn.Read(buf)  // 读取数据到缓冲区 (读取客户端发送的数据)  这里是阻塞的
		if err != nil {
			fmt.Println("Error reading:", err.Error()) // 输出错误信息
			return
		}
		command := string(buf) // 将缓冲区中的字节转换为字符串
		fmt.Println("Received command:", command)
		if command == "a" {
			fmt.Println("测试")
			return
		}
	}
}

询问了一下AI:在这种情况下,判断不通过的问题可能是由于字符串中包含了一些其他的字符,例如空格、制表符等。你可以尝试使用fmt.Printf("%q\n", command)函数来输出命令字符串,以便查看其中包含的所有字符。这个函数可以输出字符串的Go语言字面值表示,包括转义序列和不可见字符。如果命令字符串中包含了其他字符,你可以尝试对其进行修剪或替换。

\x00是ASCII码中的空字符,也称为Null字符。它通常被用作字符串的终止符,表示字符串的结束。在Go语言中,当我们创建一个长度为N的字符串时,如果字符串中只包含了M个字符(M < N),那么剩余的字符会被自动填充为N-M个Null字符。因此,当你使用make()函数创建一个长度为1024的字节数组时,在将其转换为字符串后,你可能会在字符串的末尾看到很多Null字符。如果你只想获取发送的命令字符串,你可以使用strings.TrimRight()函数来删除字符串末尾的空字符。例如,将代码中的command := strings.TrimSpace(string(buf))修改为command := strings.TrimRight(string(buf), string([]byte{0})),就可以删除字符串末尾的Null字符。

最终改为

func handleConnection(conn net.Conn) {
	defer conn.Close() // 函数返回前关闭连接

	for {
		buf := make([]byte, 1024) // 创建一个大小为1024字节的缓冲区
		n, err := conn.Read(buf)  // 读取数据到缓冲区 (读取客户端发送的数据)  这里是阻塞的
		if err != nil {
			fmt.Println("Error reading:", err.Error()) // 输出错误信息
			return
		}
		command := strings.TrimSpace(string(buf[:n])) // 将缓冲区中的字节转换为字符串 这样可以避免读取到缓冲区中多余的空字节
		fmt.Println("Received command:", command)
		fmt.Printf("%q\n", command)
		if command == "a" {
			fmt.Println("测试")
			return
		}
	}
}

这段代码之所以不会获取到 '\x00',是因为 n 表示的是实际读取的字节数,而 buf[:n] 表示将 buf 切片截取到实际读取的字节数位置,从而避免读取到未初始化的部分,也就避免了读取到 '\x00'

相比之前的代码,buf[:n] 表示只取缓冲区中实际读取的部分,而不是整个缓冲区,从而避免了读取到未初始化的部分。因为当读取到的数据不足缓冲区大小时,未被使用的缓冲区部分中可能存在未初始化的数据,这些数据会被认为是空字符 '\x00'。所以当我们直接将整个缓冲区转换为字符串时,会把未初始化部分的空字符也包含进来。而使用 buf[:n] 只取实际读取的部分,则不会包含这些未初始化的空字符。

版权声明:
作者:tianya
链接:https://tya.zone/p/105.html
来源:天涯博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
海报
conn.Read(buf)读取客户端发送的数据不符合预期
之类if判断无法通过,但是fmtprint输出看着又没啥错误 func handleConnection(conn net.Conn) { defer conn.Close() // 函数返回前关闭连接 for { bu……
<<上一篇
下一篇>>