Re: [go-nuts] "use of closed network connection" error from TCPConn.Read

5,285 views
Skip to first unread message

Dave Cheney

unread,
Jan 19, 2013, 1:58:42 AM1/19/13
to James Bardin, golan...@googlegroups.com
To quote Mr Pike, can you please describe your problem, not your solution. 

On 19/01/2013, at 11:51, James Bardin <j.ba...@gmail.com> wrote:

Please ignore my previous post (pending moderation), Read() on a TCPConn does not return (0, nil).

Since I figure I have to deal with the "use of closed network connection" in order to close a connection that's in a Read() call (unless I poll for a closing channel in between setting SetReadDeadline).This is basically the function I have to filter out this error:

func checkNetOpError(err error) error {
if err != nil {
netOpError, ok := err.(*net.OpError)
if ok && netOpError.Err.Error() == "use of closed network connection" {
return nil
}
}
return err
}


This seems awkward though; is this the best way to handle this?


--
 
 

James Bardin

unread,
Jan 19, 2013, 2:17:19 PM1/19/13
to golan...@googlegroups.com, James Bardin


On Saturday, January 19, 2013 1:58:42 AM UTC-5, Dave Cheney wrote:
To quote Mr Pike, can you please describe your problem, not your solution. 


Yeah, I didn't really give enough context.
This part of the code is a simple proxy, copying the data between two tcp connections. If either connection closes, I need to close the other half of the pair. The problem is that the other connection will almost always be in a Read() call, and will return a net.OpError with "use of closed network connection". Though I won't need to take action on other errors, I'll need to log them, as they'll be exceptional cases.

I could of course drop down to a lower level, do the copy myself, SetReadDeadline on the sockets and poll for a close signal, but that's a lot of work when to goroutines with io.Copy() works so well.

I thought it would be easier to just handle the specific error, but being relatively new to go, figuring out how to extract and match the string was a little bit of a challenge. Is this the best way to differentiate the error, or is there another way to structure the problems that I'm not thinking of?

Thanks!

Dave Cheney

unread,
Jan 19, 2013, 8:09:39 PM1/19/13
to James Bardin, golan...@googlegroups.com, James Bardin
Hi,

Here are a few suggestions.

Try +tip, this smells like a windows weirdness that should be expunged in the development version 

If you are coping data in both directions then try Shutdown rather than Close, that it what it is there for. You may need  to also use a wait group to synchronise the action of the io.Copy in the goroutine and the io.Copy in the main goroutine. 
--
 
 

James Bardin

unread,
Jan 19, 2013, 9:42:40 PM1/19/13
to golan...@googlegroups.com, James Bardin


On Saturday, January 19, 2013 8:09:39 PM UTC-5, Dave Cheney wrote:

Try +tip, this smells like a windows weirdness that should be expunged in the development version 

Yeah, tip has the same behavior. 
 
If you are coping data in both directions then try Shutdown rather than Close, that it what it is there for. You may need  to also use a wait group to synchronise the action of the io.Copy in the goroutine and the io.Copy in the main goroutine. 


I'm not following you here. A TCPConn doesn't have a Shutdown method, nor is there any reference to once in the net package.

I think have the synchronization working for what I need; if the caller gets signalled that either connection closed, it then closes the other. That second connection will almost always be in a blocking Read call.

Though, not using io.Copy, I think this is minimal example if the problem:

//
func read(conn *net.TCPConn) {
    buff := make([]byte, 1024)
    _, err := conn.Read(buff)
    if err != nil {
        fmt.Println(err)
    }
}

func main() {
    remoteAddr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:8080")
    conn, _ := net.DialTCP("tcp", nil, remoteAddr)
    go read(conn)
    time.Sleep(1 * time.Second)
    conn.Close()
}
//


Assuming you have a server on 8080, this will return
"read tcp 127.0.0.1:8080: use of closed network connection"


Thanks.

Dave Cheney

unread,
Jan 19, 2013, 9:44:59 PM1/19/13
to James Bardin, golang-nuts

Sorry about that, I was mistaken about the name.

http://golang.org/pkg/net/#TCPConn.CloseRead

--
 
 

James Bardin

unread,
Jan 19, 2013, 10:00:31 PM1/19/13
to golan...@googlegroups.com, James Bardin


On Saturday, January 19, 2013 9:44:59 PM UTC-5, Dave Cheney wrote:

Sorry about that, I was mistaken about the name.

http://golang.org/pkg/net/#TCPConn.CloseRead

Ah, now that looks promising, and from my quick tests, it's exactly what I need. I passed over trying this for some reason, probably because there wasn't much documentation.

Thanks again!
Reply all
Reply to author
Forward
0 new messages