英文:
Google Go EOF on reading from connection using Read()
问题
我正在尝试使用Google Go语言创建一个简单的TCP服务器。我有一个客户端,它指向127.0.0.1:8484。当我的服务器代码尝试读取缓冲区时,我在第37行收到一个EOF错误。客户端发送一个初始的TCP数据包,表示其客户端版本和其他设置(客户端来自游戏,因此我知道我做错了什么)。我正在尝试读取这个数据包。然而,似乎我调用读取的时机太晚了,客户端已经发送了数据包并正在等待响应。任何帮助将不胜感激,因为我真的被难住了。
package main
import (
"fmt"
"net"
"os"
)
func main() {
service := ":8484"
listener, err := net.Listen("tcp", service)
checkError(err)
fmt.Println("Login Server Started\nListening on port:", service[1:])
for {
conn, err := listener.Accept()
if err != nil {
continue
}
go handleClient(conn)
}
}
func handleClient(conn net.Conn) {
const BUFFER_LENGTH = 1024
defer conn.Close()
fmt.Println("Client connected from", conn.RemoteAddr())
var buf [BUFFER_LENGTH]byte
for {
n, err := conn.Read(buf[0:])
if err != nil {
checkError(err)
return
}
_, err2 := conn.Write(buf[0:n])
if err2 != nil {
checkError(err)
return
}
}
}
func checkError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s\n", err.Error())
os.Exit(1)
}
}
为了更清晰明了,进行了以下修改:
- 客户端连接到服务器。
- 客户端向服务器发送初始信息,例如客户端版本。
- 服务器读取缓冲区。
- 服务器响应(目前只是回显缓冲区)。
目前在读取缓冲区阶段出现问题,即n, err := conn.Read(buf[0:])
。
修复方法:我是个傻瓜,意识到我需要向客户端发送一个握手数据包。
英文:
I am trying to create a simple TCP server using the Google Go language. I have a client which points to 127.0.0.1:8484. When my server code tries to read the buffer I receive an EOF error on line 37. The client sends an initial tcp packet denoting its client version and other settings (the client is from a game therefore I know that I am doing something wrong). I am trying to read this packet. However, it seems I call the read too late and the client has already sent the packet and is waiting for its response. Any help would be appreciated, as I am truly stumped.
package main
import (
"fmt"
"net"
"os"
)
func main() {
service := ":8484"
listener, err := net.Listen("tcp", service)
checkError(err)
fmt.Println("Login Server Started\nListening on port:", service[1:])
for {
conn, err := listener.Accept()
if err != nil {
continue
}
go handleClient(conn)
}
}
func handleClient(conn net.Conn) {
const BUFFER_LENGTH = 1024
defer conn.Close()
fmt.Println("Client connected from", conn.RemoteAddr())
var buf [BUFFER_LENGTH]byte
for {
n, err := conn.Read(buf[0:])
if err != nil {
checkError(err)
return
}
_, err2 := conn.Write(buf[0:n])
if err2 != nil {
checkError(err)
return
}
}
}
func checkError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s\n", err.Error())
os.Exit(1)
}
}
Edit for clarity:
- Client connects to server.
- Client sends initial information to server e.g. client version.
- Server reads the buffer.
- Server responds (currently I am just echoing the buffer).
It is currently failing at the read buffer stage "n, err := conn.Read(buf[0:])".
Fixed: I was being an idiot and realised I needed to send a handshake packet to the client.
答案1
得分: 1
在checkError
函数中,如果从客户端读取时出现Read()
错误,你使用了显式的os.Exit(1)
,这会导致服务器被终止。
你可以改为:
n, err := conn.Read(buf[0:])
if err != nil {
fmt.Printf(err)
conn.Close()
return
}
这样会在服务器端打印错误信息,并继续监听下一个连接或继续操作。
英文:
Well, in checkError you do an explicit os.Exit(1), which kills your server if there is a Read() error from the client.
Instead of:
n, err := conn.Read(buf[0:])
if err != nil {
checkError(err)
return
}
You can do
n, err := conn.Read(buf[0:])
if err != nil {
fmt.Printf(err)
conn.Close()
return
}
Which will print the error on the server side and will go back to listening for next connection / continue to operate.
答案2
得分: 0
这对我来说是可行的,使用nc
命令:
$ nc localhost 8484
客户端连接来自 127.0.0.1:46464
你好
你好
世界
世界
^D
致命错误:EOF
退出状态 1
所以我认为你的连接处理没有问题。你可能只是发送了客户端不期望的数据,导致连接关闭。
英文:
This works for me using nc
:
$ nc localhost 8484
Client connected from 127.0.0.1:46464
hello
hello
world
world
^D
Fatal error: EOF
exit status 1
So I think there's nothing wrong with your connection handling. You might just be sending data that the client isn't expecting, and it's closing the connection because of that.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论