go语言switch case语句匹配网络接收字符串失败的根本原因及解决方案
在Go语言网络编程中,使用switch case语句处理接收到的字符串时,可能会遇到明明字符串内容正确却匹配失败的情况。本文分析一个案例,并提供有效的解决方案。
问题描述:
程序接收网络数据,提取特定部分作为action变量,用于switch case匹配。代码如下:
立即学习“go语言免费学习笔记(深入)”;
func dealwithclientmsg(conn net.Conn) { read := make([]byte, 2048) // 问题所在 readtmp := make([]byte, 1024) num, err := conn.Read(readtmp) // 注意:conn.read 应为 conn.Read if err != nil { log.Println("接受客户端消息失败:", err) // 简化错误处理 } read = append(read, readtmp[:num]...) log.Println("接收到客户端消息:", String(read)) contentlist := strings.Split(string(read), ":") // 注意:strings.split 应为 strings.Split action := strings.Trim(contentlist[0], " ") // 注意:strings.trim 应为 strings.Trim fmt.Printf("%s %Tn", action, action) // 更清晰的输出类型 switch action { case "tunnelok": fmt.Println("隧道打成功了") // ... } }
action变量的值明明是”tunnelok”,但switch语句无法匹配。直接赋值action := “tunnelok”则正常匹配。
根本原因分析:
问题出在read := make([]byte, 2048)。这行代码创建了一个长度为2048的byte切片,初始值全为0。append后,string(read)转换字符串时,前面2048个0字节也被转换为不可见的控制字符。strings.Trim只能去除空格,无法去除这些控制字符。因此,action变量实际包含不可见字符,导致匹配失败。
解决方案:
- 避免预分配过大缓冲区: 直接使用零长度切片:
var read []byte
或者:
read := []byte{}
这样避免了初始的0字节。
- 使用strings.TrimSpace: 虽然更推荐方法一,但如果必须使用预分配缓冲区,可以使用strings.TrimSpace去除首尾所有空白字符,包括不可见字符:
action := strings.TrimSpace(contentlist[0])
改进后的代码:
func dealwithclientmsg(conn net.Conn) { var read []byte readtmp := make([]byte, 1024) num, err := conn.Read(readtmp) if err != nil { log.Println("接受客户端消息失败:", err) } read = append(read, readtmp[:num]...) log.Println("接收到客户端消息:", string(read)) contentlist := strings.Split(string(read), ":") action := strings.TrimSpace(contentlist[0]) fmt.Printf("%s %Tn", action, action) switch action { case "tunnelok": fmt.Println("隧道打成功了") // ... } }
通过以上改进,可以有效解决switch case语句匹配网络接收字符串失败的问题。 记住,避免不必要的内存分配和使用合适的字符串处理函数是关键。 此外,注意代码中conn.read、strings.split和strings.trim的正确大小写。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
喜欢就支持一下吧
相关推荐