TCP连接似乎一次读取太多字节

时间:2019-04-18 11:34:36

标签: go tcp

我正在Go中编写一个FTP服务器,列出文件/目录时遇到了问题。似乎正在发生的事情是服务器正在分别正确地分别发送文件,但是从连接中读取文件时,它们一次会被读取多个。

我尝试过更改缓冲区大小以及在发送每个文件名之前发送确认,但是从连接读取时,它最终读取的字节数超出了预期。

这是来自服务器的相对部分:

for _, fn := range files {
    conn.Write([]byte(fn.Name()))
}

在上面的代码中,files[]os.FileInfo的{​​{1}},以获取当前目录中的文件。经过测试后,它会发送正确的文件名以及每个名称的正确字节。

在客户端上我有这个:

ioutil.ReadDir("./")

var buf [256]byte for i := 0; i < int(amnt); i++ { n, err = conn.Read(buf[:]) if err != nil { fmt.Printf("Error getting files: %s\n", err) } fmt.Printf("%s\n", string(buf[:n])) } 只是目录中有多少文件的int(amnt),并且是正确的。

服务器正确发送了所有内容,因此我确定问题出在读取int中,但我不知道为什么它一次要读取多个文件名。

1 个答案:

答案 0 :(得分:0)

解决此问题的一种策略可能是开发一种松散的结构化协议,该协议将涉及让客户端描述文件,服务器解析文件。这可以通过在客户端写入的每个文件之后发送新行来完成。这样,服务器可以使用go的Scanner扫描来自TCP连接的线路:

for _, fn := range files {
    conn.Write([]byte(fn.Name()))
    conn.Write([]byte(`\n`))
}
scanner := bufio.NewScanner(conn)
for {
        if ok := scanner.Scan(); !ok {
            break
        }
        fmt.Println(scanner.Text())
    }
    fmt.Println("Scanning ended")

Go之所以可行,是因为TCP connection实现了io.Reader接口。