Golang TCP connection writing/sending being closed

Viewed 39

I have a simple TCP server-client, for a project i want to do. When i try to check if the connection has being closed, i simply Write/Read and check if an error occured, i catch it and if it is a broken pipe error i handle it.

But i came to a point when always that i close the client, the server needs to write/read two times in order to through the error, i dont have an extensive knowledge on sockets but seems weird to me that its able to write or even read from a closed connection.

Is it normal? Thank you so much

Server:

package main
import (
    "log"
    "net"
    "os"
    "time"
    "errors"
    "syscall"
)

const (
    HOST = ""
    PORT = "11"
    TYPE = "tcp"
)

func main() {
    listen, err := net.Listen(TYPE, HOST+":"+PORT)
    if err != nil {
        log.Fatal(err)
        os.Exit(1)
    }
    // close listener
    defer listen.Close()
    for {
        conn, err := listen.Accept()
        if err != nil {
            log.Fatal(err)
            os.Exit(1)
        }
        go handleIncomingRequest(conn)
    }
}
func handleIncomingRequest(conn net.Conn) {
    // store incoming data
    buffer := make([]byte, 1024)
    _, err := conn.Read(buffer)
    if err != nil {
        log.Fatal(err)
    }
    // respond
    for {
        n, err := conn.Write([]byte("Hi back!\n"))
        log.Println(n)
        if err != nil {
            if errors.Is(err, syscall.EPIPE) {
                conn.Close()
                log.Print("This is broken pipe error")
                return
            }
        }
        reply := make([]byte, 1024)
        _, err = conn.Read(reply)
        if err != nil {
            if errors.Is(err, syscall.EPIPE) {
                conn.Close()
                log.Print("This is broken pipe error")
                return
            }
        }
        log.Println(string(reply))
        time.Sleep(30 * time.Second)
    }
    conn.Close()
    // close conn
}

Client:

package main

import (
    "fmt"
    "log"
    "net"
)

func main() {

    con, err := net.Dial("tcp", "localhost:11")

    checkErr(err)

    defer con.Close()

    msg := "hola"

    _, err = con.Write([]byte(msg))

    checkErr(err)
    for {
        reply := make([]byte, 1024)

        _, err = con.Read(reply)

        checkErr(err)

        fmt.Println(string(reply))
        _, err = con.Write([]byte("Eyy\n"))
        checkErr(err)
    }
}

func checkErr(err error) {

    if err != nil {

        log.Fatal(err)
    }
}

Output Server:

go run main_server.go
2022/09/22 13:05:50 9
2022/09/22 13:05:50 Eyy

2022/09/22 13:06:20 9
2022/09/22 13:06:20
2022/09/22 13:06:50 0
2022/09/22 13:06:50 This is broken pipe error

Output Client:

go run main_client.go
Hi back!
^Csignal: interrupt
0 Answers
Related