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
来源:天涯博客
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论