gpt4 book ai didi

Golang TCP 客户端不从服务器接收数据,在 conn.Read() 上挂起/阻塞

转载 作者:IT王子 更新时间:2023-10-29 02:04:11 31 4
gpt4 key购买 nike

我正在深入研究 Go 的网络方面,我想我应该从 TCP 客户端和服务器开始。

我能够让客户端连接到服务器并成功发送一条简单消息(“Hello”)。但是,我无法让服务器发回响应(或让客户端读取响应)。

这是代码。

服务器

Address := "localhost:9999"
Addr, err := net.ResolveTCPAddr("tcp", Address)
if err != nil {
log.Fatal(err)
}

listener, err := net.ListenTCP("tcp", Addr)
if err != nil {
log.Fatal(err)
}
defer listener.Close()

//server loop
for {
conn, err := listener.Accept()
if err != nil {
continue
}

go handle(conn)
}

func handle(c net.Conn) {

totalBytes, message := connRead(c)
fmt.Println(c.RemoteAddr())

fmt.Println(string(message[:totalBytes]))

c.Write([]byte("Hi"))
fmt.Println("Replied")
c.Close()
}

func connRead(c net.Conn) (int, []byte) {
buffer := make([]byte, 4096)
totalBytes := 0

for {
n, err := c.Read(buffer)
totalBytes += n
if err != nil {
if err != io.EOF {
log.Printf("Read error: %s", err)
}
break
}

}
return totalBytes, buffer
}

客户端

    tcpAddr, err := net.ResolveTCPAddr("tcp", "localhost:9999")
if err != nil {
log.Fatal(err)
}
conn, err := net.DialTCP("tcp", nil, tcpAddr)
if err != nil {
log.Fatal(err)
}
defer conn.Close()

_, err = conn.Write([]byte("Hello"))
if err != nil {
log.Fatal(err)
}

tBytes, resp := connRead(conn)
fmt.Println(tBytes)
fmt.Println(string(resp[:tBytes]))

func connRead(c net.Conn) (int, []byte) {
buffer := make([]byte, 4096)
totalBytes := 0

for {
fmt.Println("Stuck?")
n, err := c.Read(buffer)
fmt.Println("Stuck.")
totalBytes += n
fmt.Println(totalBytes)
if err != nil {
if err != io.EOF {
log.Printf("Read error: %s", err)
}
break
}

}
return totalBytes, buffer
}

据我所知,这不是服务器的问题。当我运行客户端时,一切都在 fmt.Println("Stuck?") 之后停止。这让我相信它以某种方式在 n, err := c.Read(buffer) 语句中搞砸了。服务器甚至不打印消息长度 (5) 和消息 ("Hello"),直到我按 Ctrl-C 客户端。如果我在客户端中注释掉读取和打印,那么事情就会顺利进行。

我试过在谷歌上搜索答案,但一无所获。

我做错了什么?我在客户端使用 conn.Read() 是不是错了?

编辑:

我确实可以访问 Linux,所以这里是相关函数的 SIGQUIT 转储。

服务器

http://pastebin.com/itevngCq

客户端

http://pastebin.com/XLiKqkvs

最佳答案

for {
n, err := c.Read(buffer)
totalBytes += n
if err != nil {
if err != io.EOF {
log.Printf("Read error: %s", err)
}
break
}

}

这是因为您正在从连接读取直到发生 EOF 错误

conn.Write([]byte("Hello"))

在你真正关闭连接之前,上面的语句根本不会到达EOF

在客户端按下 ctrl+c 连接将被关闭,所以 EOF 发生在服务器端,这就是它退出服务器端 for 循环并打印这些的原因

127.0.0.1:****
Hello
Replied

如果你想让它工作,你不应该在 EOF 之前读取连接

还有很多其他的选择

  1. 选择一个定界符并在服务器上读取直到出现定界符并在之后响应。看看这个 link
  2. 在发送实际消息之前发送要从客户端读取的字节数,首先从服务器端读取要读取的字节数,然后从连接中读取这些字节数

关于Golang TCP 客户端不从服务器接收数据,在 conn.Read() 上挂起/阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38646224/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com