英文:
when using fmt.Printf() many blanks are displayed
问题
我正在尝试使用Go语言完成一个回显服务器。服务器代码如下:
// 使用TCP回显时间
func main() {
// 监听本地的TCP端口8000
listener, err := net.Listen("tcp", "localhost:8000")
if err != nil {
fmt.Fprintf(os.Stderr, "监听错误,%s", err)
return
}
for {
// 接受连接
connection, err := listener.Accept()
if err != nil {
fmt.Fprintf(os.Stderr, "监听错误,%s\n", err)
} else {
handle(connection)
}
}
}
// 处理TCP连接
// 每隔一秒返回当前时间
func handle(connection net.Conn) {
defer connection.Close()
for {
// 返回写入的字节数和错误
if _, err := fmt.Fprintf(connection, time.Now().Format("15:04:05\n")); err != nil {
// 写入错误,可能是客户端关闭了连接
fmt.Fprintf(os.Stderr, "%s 关闭连接\n", connection.RemoteAddr())
break
}
// 等待一秒
time.Sleep(1 * time.Second)
}
}
客户端代码如下:
package main
const (
proto = "tcp"
addr = "localhost:8000"
)
func main() {
// 客户端连接到TCP端口localhost:8000
connection, err := net.Dial(proto, addr)
if err != nil {
fmt.Fprintf(os.Stderr, "连接到 %s 错误,%s", addr, err)
} else {
buf := make([]byte, 1024)
for {
if _, err := connection.Read(buf); err != nil {
fmt.Fprintf(os.Stderr, "从 %s 读取错误,%s\n", addr, err)
break
} else {
fmt.Printf("数据:%s 结束\n", buf)
}
}
}
}
当我运行我的代码时,得到了如下结果:
我不知道为什么会显示这么多空白字符。我猜可能是内置函数make
导致的,但为什么Go语言默认会在字符串末尾显示这么多空白字符,而其他高级语言不会呢?你能解释并修复这个问题吗?
英文:
I'm trying to complete an echo server using golang.
server like this:
// use tcp to echo time
func main() {
// listen tcp localhost:8000
listener, err := net.Listen("tcp", "localhost:8000")
if err != nil {
fmt.Fprintf(os.Stderr, "listen error, %s", err)
return
}
for {
// accept
connection, err := listener.Accept()
if err != nil {
fmt.Fprintf(os.Stderr, "listen error, %s\n", err)
} else {
handle(connection)
}
}
}
// handle the tcp connection
// return the time in one second gap
func handle(connection net.Conn) {
defer connection.Close()
for {
// return written bytes, err
if _, err := fmt.Fprintf(connection, time.Now().Format("15:04:05\n")); err != nil {
// write error, probably the client close the connection
fmt.Fprintf(os.Stderr, "%s close connection\n", connection.RemoteAddr())
break
}
// wait one second
time.Sleep(1 * time.Second)
}
}
client like this
package main
const (
proto = "tcp"
addr = "localhost:8000"
)
func main() {
// client connect to tcp localhost:8000
connection, err := net.Dial(proto, addr)
if err != nil {
fmt.Fprintf(os.Stderr, "connect to %s error, %s", addr, err)
} else {
buf := make([]byte, 1024)
for {
if _, err := connection.Read(buf); err != nil {
fmt.Fprintf(os.Stderr, "read from %s error, %s\n", addr, err)
break
} else {
fmt.Printf("data:%s ending\n", buf)
}
}
}
}
When I run my code I get the following result:
I have no idea why so many blanks are shown.
I guess it's probably caused by the built-in function make, but why golang by default, displays so many blanks at the end of a string, unlike other high-level languages?
Could explain this and fix it?
答案1
得分: 3
Read返回n,表示读取的字节数。不要忽略它。将其读入长度为cap(buf)的缓冲区:buf[:cap(buf)]
。然后使用n来更新缓冲区的长度:buf = buf[:n]
。
buf := make([]byte, 0, 1024)
for {
n, err := connection.Read(buf[:cap(buf)])
buf = buf[:n]
if err != nil {
fmt.Fprintf(os.Stderr, "从%s读取错误,%s\n", addr, err)
break
}
fmt.Printf("数据:%s 结束\n", buf)
}
英文:
Read returns n, the number of bytes read. Don't ignore it. Read into a buffer of length cap(buf): buf[:cap(buf)]
. Then use n to update the buffer length: buf = buf[:n]
.
buf := make([]byte, 0, 1024)
for {
n, err := connection.Read(buf[:cap(buf)])
buf = buf[:n]
if err != nil {
fmt.Fprintf(os.Stderr, "read from %s error, %s\n", addr, err)
break
}
fmt.Printf("data:%s ending\n", buf)
}
答案2
得分: -1
你是对的,内置的make函数会声明一个长度和容量都为1024的切片。更好的处理方法是使用一个协议,该协议可以首先读取消息体的大小,然后声明适合响应体的大小。
英文:
You are right, built-in make declare a slice with length and capacity equals to 1024.The better way to deal with such info is to use a protocol which can first read the size of the body, and declare the fit size of the reponse body.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论