【问题标题】:EOF error when reading from port with bufio使用 bufio 从端口读取时出现 EOF 错误
【发布时间】:2025-12-22 08:50:11
【问题描述】:

我正在尝试学习 net 包。我正在侦听端口上的本地连接,并使用echo -n "Server test.\n" | nc localhost 5000 向该端口发送数据。

但是,我在读取数据时总是收到 EOF 错误。我检查了文档,这应该只发生在when there is no more input available,但是我不明白为什么会在这里发生。

这是我的代码:

package main

import (
    "bufio"
    "fmt"
    "net"
    "os"
)

// Connection details
type connection struct {
    host    string
    port    string
    network string
}

// Initialise a Listener on a given port
// Pass handling into seperate goroutine
func main() {
    localConn := connection{
            host:    "", // Localhost
            port:    "5000",
            network: "tcp",
    }

    listener, err := net.Listen(localConn.network, localConn.host+":"+localConn.port)
    checkError("Error listening: ", err)

    conn, err := listener.Accept()
    for {
            checkError("Error accepting: ", err)
            go handleRequest(conn)
    }
}

// Delegate handling of requests
func handleRequest(conn net.Conn) {
    // Read message up until newline delimiter
    message, err := bufio.NewReader(conn).ReadString('\n')
    checkError("Error reading: ", err)

    fmt.Println("Message recieved: ", string(message))
    conn.Write([]byte("Recieved message: " + string(message) + "\n"))

    conn.Close()
}

// Check if an error exists
// If so, print and exit program. (Not super robust!)
func checkError(message string, err error) {
    if err != nil {
            fmt.Println(message, err.Error())
            os.Exit(1)
    }
}

【问题讨论】:

    标签: networking go tcp port


    【解决方案1】:

    您似乎错误地使用了echo。标志 -e 将两个字符 \n 解释为换行符(检查 here)。

    使用以下命令向服务器发送数据:

    echo -e "Server test.\n" | nc localhost 5000
    

    除此之外,您还应该修复 for 循环:

    for {
        conn, err := listener.Accept()
        checkError("Error accepting: ", err)
        go handleRequest(conn)
    }
    

    在您的原始代码中,您只接受一个连接。之后,for 循环会启动更多的 goroutines 尝试在关闭的连接上读取(无论错误与否,首先 handleRequest 调用会关闭连接)。

    【讨论】:

      【解决方案2】:

      一个问题出在以下几行:

      conn, err := listener.Accept()
      for {
              checkError("Error accepting: ", err)
              go handleRequest(conn)
      }
      

      应用程序在循环中启动 goroutine 以读取单个连接。第一个读取连接的 goroutine 成功。后面的 goroutine 报错。

      将代码改为:

      for {
              conn, err := listener.Accept()
              checkError("Error accepting: ", err)
              go handleRequest(conn)
      }
      

      客户端未按服务器预期发送换行符。使用此命令发送消息:

      echo "Server test." | nc localhost 5000
      

      【讨论】: