Hi Alex Thanks for your suggestion, I have implemented it, but something is still not quite right, the first iteration of the loop to write to the conn still encounters a temporary error, even though the internal error is a syscall.ECONNRESET.
Please see the updated code below func TestRemotelyClosedConnectionDetectedOnWrite(t *testing.T) { listener, err := net.Listen("tcp", ":0") if err != nil { t.Fatal(err) } wait := make(chan struct{}) go func() { conn, err := listener.Accept() if err != nil { panic(err) } err = conn.(*net.TCPConn).SetLinger(0) if err != nil { panic(err) } err = conn.Close() if err != nil { panic(err) } wait <- struct{}{} }() conn, err := net.Dial("tcp", listener.Addr().String()) if err != nil { t.Fatal(err) } err = conn.(*net.TCPConn).SetLinger(0) if err != nil { t.Fatal(err) } <-wait // Allow ample time for any network communication to complete time.Sleep(time.Second) for i := 0; i < 10; i++ { println(i) _, err = conn.Write([]byte("b")) if neterr, ok := err.(*net.OpError); ok { if e, ok := neterr.Err.(*os.SyscallError); ok { if e.Err == syscall.ECONNRESET && neterr.Temporary() { // ECONNRESET should not be a temporary error println("ECONNRESET is not permanent?") t.Fail() } } } if neterr, ok := err.(*net.OpError); ok && !neterr.Temporary() { break } } if err == nil { t.Fatal("expecting error to be returned when writing") } if neterr, ok := err.(net.Error); ok && !neterr.Temporary() { return } t.Fatal("expecting error to be a permanent net.OpError", err) } On Tuesday, April 10, 2018 at 5:16:09 PM UTC+1, Alex Efros wrote: > > Hi! > > On Tue, Apr 10, 2018 at 07:58:29AM -0700, pierspo...@gmail.com > <javascript:> wrote: > > I'm trying to understand what is going on under the hood here. > > SO_LINGER (see socket(7)) delay happens. Add this after Accept(): > > conn, err := listener.Accept() > if err == nil { > err = conn.(*net.TCPConn).SetLinger(0) > } > > > I would expect a net.Conn after being closed from the far side, to issue > an > > error if the near side then tries to write to it. On my local machine an > > error is returned on the second write, on the go playground all writes > > succeed. > > Playground doesn't support TCP, and there is write buffering which > postpone returning related error. > > https://play.golang.org/p/JTAetL9no2y > > This example correctly output error in playground: > 0 > 2009/11/10 23:00:00 set tcp 0.0.0.0:2->127.0.0.1:3: Protocol not > available > and correctly works outside of playground: > 0 > 1 > 2 > 3 > 4 > write tcp 127.0.0.1:38900->127.0.0.1:33199: write: connection reset > by peer > (on very slow system it may output few more numbers because time.Sleep is > not really suitable for synchronization). > > -- > WBR, Alex. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.