Home > Software design >  Why does net.Conn.close() seem to be closing at the wrong time?
Why does net.Conn.close() seem to be closing at the wrong time?

Time:04-23

I'm trying to read and write some commands from a TCP client. I want to close a connection after the last function has been executed but for some reason, it seems like the server disconnects the connection in the middle of the function even when explicitly placed afterward.

    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)
    }
}

That means the client trying to communicate backward simply isn't able to communicate but the program runs to the end.

CodePudding user response:

Goroutines are asynchronous so after calling handleConn here:

go handleConn(conn)
conn.Close()

the main function continues to execute and closes the connection. Try just calling the handleConn function regularly (without the go).

CodePudding user response:

You can also use 'defer' to close the connection after the main end:

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)
        defer conn.Close()
    }

}
  • Related