Golang中net/http Accept()在Linux上阻塞整个程序的问题探讨
Golang中net/http Accept()在Linux上阻塞整个程序的问题探讨
你好! 😊
我目前正在开发一个我分叉的开源项目
( https://github.com/sagneta/go-rtsengine )
但来自 GitHub 的代码在以下代码段处停止运行:
listener, err := net.Listen("tcp", "localhost:8082")
if err != nil {
return err
}
fmt.Printf("1") //Prints 1
conn, err := listener.Accept()
fmt.Printf("2") //Never prints 2
我是 Go 语言的新手,对此感到非常困惑,现在该怎么办。我是应该更换标准库,还是降级 Go 版本?
我当前的版本是 go1.10.2 linux/amd64,使用的是 Manjaro Linux。
非常感谢任何帮助!
更多关于Golang中net/http Accept()在Linux上阻塞整个程序的问题探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html
非常感谢! 这确实很愚蠢,但如果没有你的帮助,我可能会一直卡在那里 😊
更多关于Golang中net/http Accept()在Linux上阻塞整个程序的问题探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
好的,listener.Accept() 会一直等待,直到在 8082 端口有传入的 TCP 连接。
因此,连接到该端口,你的程序就会继续执行。
net package - net - Go Packages
Package net provides a portable interface for network I/O, including TCP/IP, UDP, domain name resolution, and Unix domain sockets.
type Listener interface { // Accept waits for and returns the next connection to the listener. Accept() (Conn, error) // [...] }
这是一个常见的网络编程问题,主要原因是Accept()方法在没有客户端连接时会阻塞当前goroutine。在Go语言中,这通常不会"阻塞整个程序",但会阻塞当前goroutine的执行流程。
问题分析:
fmt.Printf("1")正常输出,说明net.Listen成功fmt.Printf("2")没有输出,说明程序在listener.Accept()处阻塞等待客户端连接
解决方案是使用goroutine来处理连接接受,或者在实际使用场景中确保有客户端连接到指定端口。
示例代码:
package main
import (
"fmt"
"net"
"time"
)
func main() {
listener, err := net.Listen("tcp", "localhost:8082")
if err != nil {
fmt.Printf("Listen error: %v\n", err)
return
}
fmt.Printf("1 - Server started on localhost:8082\n")
// 方案1: 使用goroutine异步接受连接
go func() {
conn, err := listener.Accept()
if err != nil {
fmt.Printf("Accept error: %v\n", err)
return
}
fmt.Printf("2 - Connection accepted from: %v\n", conn.RemoteAddr())
conn.Close()
}()
// 保持主程序运行
time.Sleep(10 * time.Second)
fmt.Println("Server shutting down")
}
或者使用一个完整的服务器示例:
package main
import (
"fmt"
"net"
"io"
)
func handleConnection(conn net.Conn) {
defer conn.Close()
fmt.Printf("Handling connection from: %v\n", conn.RemoteAddr())
// 简单的echo服务器
io.Copy(conn, conn)
}
func main() {
listener, err := net.Listen("tcp", "localhost:8082")
if err != nil {
fmt.Printf("Listen error: %v\n", err)
return
}
defer listener.Close()
fmt.Printf("Server listening on localhost:8082\n")
for {
conn, err := listener.Accept()
if err != nil {
fmt.Printf("Accept error: %v\n", err)
continue
}
fmt.Printf("Accepted connection from: %v\n", conn.RemoteAddr())
go handleConnection(conn)
}
}
要测试这个服务器,可以在另一个终端使用telnet或nc连接:
telnet localhost 8082
# 或者
nc localhost 8082
关于版本问题:Go 1.10.2确实比较旧,建议升级到更新的稳定版本(如Go 1.21+),但这个问题与Go版本无关,是网络编程的正常行为。标准库net/http不需要更换,这是正确的使用方式。

