当Go中的套接字断开连接时,我能知道它是好是坏吗?

Say I open a connection to a server like:

conn, _ := net.DialTimeout("tcp", "127.0.0.1:2121", 10000000)

and I do some stuff and then call

conn.Close()

that's option 1. But what if I don't call Close on the conn and just call

os.Exit(1)

leaving the connection still open. That's option 2. i.e. I'm trying to simulate a user uploading a file and either reaching the ending and really Closing the connection... or ending the stream being writen to the socket but never officially closing it.

Back on the server side, is there anyway to tell which event happened? The good Close or the bad one?

Does net.Listener have like some sort of callback to let me know. Because when I just call:

n, err := serverConn.Read()

I get an EOF err in either case, good or bad.

It depends on the operating system. The one you're on clearly does a graceful close for you if your process exits with an unclosed socket, so it is equivalent to 'good'. With the other kind you will get an ECONNRESET.

You should call Read like this:

 var done,closeCh chan struct{}

 func readLoop(c net.Conn) {
   for {
       n,err := conn.Read(buf)
       // check n and err
       close(closeCh)
       // or
       close(done)
   }
}


func handle(conn net.Conn) {
     go readLoop(conn)
     select {
       case <-closeCh:
         println("closed")
       case <-done:
         println("done")
     }
}

I know this isn't an answer but I can't comment and it's extremely frustrating because I tried to suggest an edit to just ask this question, and this app told me I couldn't after I wrote it. Please be merciful.

@EJP Can you provide a source? I know what you're saying is true for C but almost literally everything is safe to let the GC handle for closes on program termination in Go. I'd wager it has nothing to do with the OS (but I could be mistaken) as the GC probably handles closing the socket properly for you anyways (see all the libraries which explain "you can save time by ommiting 'Close' if the program execution is terminating"). I'm considering asking a question of how far that goes but I've run into exactly one case where it doesn't handle the cleanup (and it's certainly not in a standard lib).