33

为了自学 Go,我正在构建一个简单的服务器,它接受一些输入、进行一些处理并将输出发送回客户端(包括原始输入)。

输入的长度可以从大约 5 到 13 个字符 + 结束行以及客户端发送的任何其他内容不等。

输入被读入字节数组,然后转换为字符串进行一些处理。另一个字符串附加到该字符串,整个内容被转换回字节数组以发送回客户端。

问题是输入填充了一堆 NUL 字符,我不知道如何摆脱它们。

所以我可以遍历数组,当我遇到一个 nul 字符时,记下长度 (n),创建一个该长度的新字节数组,然后将前 n 个字符复制到新字节数组并使用它。这是最好的方法,还是有什么可以让我更轻松?

一些精简的代码:

data := make([]byte, 16)
c.Read(data)

s := strings.Replace(string(data[:]), "an", "", -1)
s = strings.Replace(s, "\r", "", -1)
s += "some other string"
response := []byte(s)
c.Write(response)
c.close()

此外,如果我在这里做任何其他明显愚蠢的事情,我会很高兴知道。

4

4 回答 4

68

在包“bytes”中,func Trim(s []byte, cutset string) []byte是你的朋友:

Trim 通过切掉 cutset 中包含的所有前导和尾随 UTF-8 编码的 Unicode 代码点来返回 s 的子切片。

// Remove any NULL characters from 'b'
b = bytes.Trim(b, "\x00")
于 2013-03-15T11:43:26.593 回答
6

你的方法听起来基本正确。一些备注:

  1. 找到第一个 nul 字节的索引后data,不需要复制,只需截断切片:data[:idx]

  2. bytes.Index应该能够为您找到该索引。

  3. 还有,bytes.Replace所以你不需要转换为字符串。

于 2013-03-15T11:38:38.003 回答
3

io.Reader文档说:

Read 最多将 len(p) 个字节读入 p。它返回读取的字节数 (0 <= n <= len(p)) 和遇到的任何错误。

如果应用程序中对 Read 的调用未读取 16 个字节,data则将有尾随零字节。使用读取的字节数来修剪缓冲区中的零字节。

data := make([]byte, 16)
n, err := c.Read(data)
if err != nil {
   // handle error
}
data = data[:n]

还有一个问题。不能保证 Read 会吞下对等方发送的所有“消息”。应用程序可能需要多次调用 Read 才能获得完整的消息。

您在问题中提到了结尾。如果来自客户端的消息被终止但换行符,则使用bufio.Scanner从连接中读取行:

 s := bufio.NewScanner(c)
 if s.Scan() {
     data = s.Bytes() // data is next line, not including end lines, etc.
 }
 if s.Err() != nil {
     // handle error
 } 
于 2021-04-17T00:33:38.113 回答
0

您可以利用的返回值Read

package main
import "strings"

func main() {
   r, b := strings.NewReader("north east south west"), make([]byte, 16)
   n, e := r.Read(b)
   if e != nil {
      panic(e)
   }
   b = b[:n]
   println(string(b) == "north east south")
}

https://golang.org/pkg/io#Reader

于 2021-04-10T03:44:39.180 回答