为什么 net.Conn.close() 似乎在错误的时间关闭?
Why does net.Conn.close() seem to be closing at the wrong time?
我正在尝试从 TCP 客户端读取和写入一些命令。我想在执行完最后一个函数后关闭连接,但由于某种原因,服务器似乎在函数中间断开了连接,即使之后明确放置也是如此。
package main
import (
"bufio"
"fmt"
"io"
"log"
"net"
"strconv"
"strings"
"time"
)
func main() {
listener, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Print(err)
}
go handleConn(conn)
conn.Close()
}
}
func handleConn(someconnection net.Conn) {
func1(someconnection)
func2(someconnection) //connection drops in the middle of executing this part
}
func func2(someconnection net.Conn) {
//send message(a string)
_, err := io.WriteString(someconnection, dosomething)
if err != nil {
log.Fatal(err)
}
//await reply
//send another message
_, err = io.WriteString(someconnection, dosomething)
if err != nil {
log.Fatal(err)
}
//await reply
//send another message, connection tends to close somewhere here
_, err = io.WriteString(someconnection, dosomething)
if err != nil {
log.Fatal(err)
}
//await,send
_, err = io.WriteString(someconnection, do something)
if err != nil {
log.Fatal(err)
}
//await, read and print message
c := bufio.NewReader(someconnection)
buff1 := make([]byte, maxclientmessagelength)
buff1, err = c.ReadBytes(delimiter)
fmt.Printf("\n%s\n", buff1)
_, err = io.WriteString(someconnection, dosomething)
if err != nil {
log.Fatal(err)
}
}
这意味着尝试向后通信的客户端根本无法通信,但程序运行到最后。
更新 1:
通过将延迟关闭语句放置在首次获取连接时取得了一些进展。
func main() {
listener, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Print(err)
}
defer conn.Close()
go handleConn(conn)
}}
现在它不一定会在一秒钟内关闭我希望它会关闭但至少它现在一直在运行。
Goroutines 是异步的,所以在这里调用 handleConn 后:
go handleConn(conn)
conn.Close()
main函数继续执行并关闭连接。
尝试定期调用 handleConn 函数(没有 go
)。
conn.Close
需要在 handleConn
完成其工作后完成。您可以使用通道将回传给主线程,但这太复杂了(并且还会阻止主线程的执行)。应该这样做
func main() {
listener, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Print(err)
}
go handleConn(conn)
// REMOVE BELOW LINE
// conn.Close()
}
}
在handleConn
里面添加conn.Close
func handleConn(someconnection net.Conn) {
// ADD BELOW LINE
defer someconnection.Close()
func1(someconnection)
func2(someconnection)
}
这确保 conn.Close
在 func1
和 func2
执行完成后调用
我正在尝试从 TCP 客户端读取和写入一些命令。我想在执行完最后一个函数后关闭连接,但由于某种原因,服务器似乎在函数中间断开了连接,即使之后明确放置也是如此。
package main
import (
"bufio"
"fmt"
"io"
"log"
"net"
"strconv"
"strings"
"time"
)
func main() {
listener, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Print(err)
}
go handleConn(conn)
conn.Close()
}
}
func handleConn(someconnection net.Conn) {
func1(someconnection)
func2(someconnection) //connection drops in the middle of executing this part
}
func func2(someconnection net.Conn) {
//send message(a string)
_, err := io.WriteString(someconnection, dosomething)
if err != nil {
log.Fatal(err)
}
//await reply
//send another message
_, err = io.WriteString(someconnection, dosomething)
if err != nil {
log.Fatal(err)
}
//await reply
//send another message, connection tends to close somewhere here
_, err = io.WriteString(someconnection, dosomething)
if err != nil {
log.Fatal(err)
}
//await,send
_, err = io.WriteString(someconnection, do something)
if err != nil {
log.Fatal(err)
}
//await, read and print message
c := bufio.NewReader(someconnection)
buff1 := make([]byte, maxclientmessagelength)
buff1, err = c.ReadBytes(delimiter)
fmt.Printf("\n%s\n", buff1)
_, err = io.WriteString(someconnection, dosomething)
if err != nil {
log.Fatal(err)
}
}
这意味着尝试向后通信的客户端根本无法通信,但程序运行到最后。
更新 1:
通过将延迟关闭语句放置在首次获取连接时取得了一些进展。
func main() {
listener, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Print(err)
}
defer conn.Close()
go handleConn(conn)
}}
现在它不一定会在一秒钟内关闭我希望它会关闭但至少它现在一直在运行。
Goroutines 是异步的,所以在这里调用 handleConn 后:
go handleConn(conn)
conn.Close()
main函数继续执行并关闭连接。
尝试定期调用 handleConn 函数(没有 go
)。
conn.Close
需要在 handleConn
完成其工作后完成。您可以使用通道将回传给主线程,但这太复杂了(并且还会阻止主线程的执行)。应该这样做
func main() {
listener, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Print(err)
}
go handleConn(conn)
// REMOVE BELOW LINE
// conn.Close()
}
}
在handleConn
conn.Close
func handleConn(someconnection net.Conn) {
// ADD BELOW LINE
defer someconnection.Close()
func1(someconnection)
func2(someconnection)
}
这确保 conn.Close
在 func1
和 func2
执行完成后调用