为什么连接读取返回缓冲区的长度,而不是真正发送?



我正在用Golang编写一对套接字服务器和客户端。

这是我给客户的代码:

func handler(conn net.Conn) {
defer conn.Close()
buffer := make([]byte, 2048)
reader := bufio.NewReader(os.Stdin)
for {
nbytes, err := reader.Read(buffer)
if err != nil {
if err == io.EOF {
break
}
log.Fatal(err)
}
log.Printf("client: send %d bytes -> %s", nbytes, buffer)
_, err = conn.Write(buffer)
if err != nil {
log.Fatal(err)
}
}
}

服务器代码:

func serverHandler(conn net.Conn) {
defer conn.Close()
buffer := make([]byte, 2048)
for {
nbytes, err := conn.Read(buffer)
if err != nil {
if err == io.EOF {
break
}
log.Print("Error reading: ", err.Error())
}
log.Printf("server: %d bytes received -> %s", nbytes, buffer)
writer := bufio.NewWriter(os.Stdout)
_, err = writer.Write(buffer)
if err != nil {
log.Print("Error writing: ", err.Error())
}
writer.Flush()
}
}

下面是一些输出:

./server 12345
2019/12/24 00:35:31 Listen on localhost:12345
2019/12/24 00:35:38 client from: 127.0.0.1:51352
2019/12/24 00:35:48 server: 2048 bytes received -> hello?

./client localhost 12345
hello?
2019/12/24 00:35:48 client: send 7 bytes -> hello?

如您所见,客户端发送了 7 个字节,但服务器接收了 2048 个字节。 服务器代码有什么问题?

你没有发送 7 个字节,而是发送了 2048 个字节。您将buffer传递给conn.Write,它会写入它的所有 2048 字节。要仅发送读取的字节数,您应该只发送包含您读取的数据的部分:

_, err = conn.Write(buffer[:nbytes])

要避免此问题,请使用此安全buf习惯用语作为Read。在此示例中,它将写入读取的字节数。

buf := make([]byte, 2048)
for {
n, err := conn.Read(buf[:cap(buf)])
buf = buf[:n]
if err != nil {
// handle error
}
_, err = w.Write(buf)
}

相关内容

最新更新