代码片段如下:
func dealWithClientMsg(conn net.Conn) {
read := make([]byte, 2048)
readTmp := make([]byte, 1024)
num, err := conn.Read(readTmp)
if err != nil {
log.Println("接受客户端消息失败:", err.Error())
}
read = append(read, readTmp[:num]...)
log.Println("接收到客户端消息:", string(read))
contentList := strings.Split(string(read), ":")
action := strings.Trim(contentList[0], " ")
//action := "TUNNELOK"
fmt.Printf("%s%T",action, action) //此处输出结果:TUNNELOKstring
switch action {
case "TUNNELOK":
fmt.Println("隧道打成功了")
......
}
}
代码中的 action 变量可以确定是 TUNNELOK 了,但是 swich 里面 就是匹配不到,我如果直接将 action 变量的值赋值为 TUNNELOK ,则可以匹配到,实在没法了,遂请问高人这是为何?谢谢指点,小弟感激涕零。
解决方案
改为
试一下。
TrimSpace()
会 trim 掉所有不可见字符,包括\r
、\n
、\t
这些。这是可能的解决方案,再说一下我猜测的原因。
原因推测
你在问题评论里说
len(action)
的长度是2056
,这个2056
是怎么来的呢?大概是
TUNNELOK
的长度(8)加上了 2048(read := make([]byte, 2048)
)。关键在于这几句代码:
首先,
make([]byte, 2048)
会按照参数里的长度给slice
初始化成一个容量和长度都为 2048 的切片,内容是零值。你可以在
make
下面打印一下read
的内容、长度、容量(cap
),会发现它的内容是[0 0 0 0 0 0 0 0 ...(省略)]
,即read
内部已经有 2048 个元素了。紧接着你执行了
append
,它会把readTmp[:num]...
的内容给追加到read
的 2048 位之后,所以此时read
的长度就是2048 + len(readTmp[:num])
了。然后是第三句,这句其实有两个逻辑:
重点在第一句。
string(read)
会直接把[]byte
转成string
,而此时你的read
已经是一个前 2048 位都是 0 的slice
了,这 2048 个 0 也会被转成string
,也就是 ASCII 码里为 0 的字符,这是个不可见字符。这应该就是根本原因了。
根治方法
最上面提供了
TrimSpace
的解决方案,但这个办法依然会浪费 2048 位空间。如果要进一步根治的话,也很简单:
read
不要用make
去初始化,改成下面两种就行:至于
readTmp
要不要也这么改,你可以自己试一下。