In my golang program, I use io.Copy()
to relay the flow between end1 and end2.
func relay(src, dst net.Conn, stop chan bool) {
stop <- (io.Copy(src, dst) == nil)
}
func myprog(e1, e2 net.Conn) {
stop := make(chan bool)
go relay(e1, e2, stop)
go relay(e2, e1, stop)
result := <-stop
// Which end causes failure? Or both of them?
}
When one of the relay failed, how can I find out which end is closed/dropped. By result? Or call some member function of e1/e2?
Thanks.
First, making two relay
sharing a channel and returning an error with no information of which relay
it is from, obviously is not helping to understanding which endpoint is faulty.
Second, you can wrap Read and Write method of each endpoint to notify the error, like:
type errReader struct {
r io.Reader
err error
}
func (er *errReader) Read(b []byte) (int, error) {
n, err := er.r.Read(b)
er.err = err
return n, err
}
type errWriter struct {
w io.Writer
err error
}
func (ew *errWriter) Write(b []byte) (int, error) {
n, err := ew.w.Write(b)
ew.err = err
return n, err
}
Note: The above code takes no consideration of concurrent read or write, nor continuation after error (which may set the err value back to nil again) though it should not be a problem for io.Copy
. It also does not ignore io.EOF
error, so you may want to check it explicitly.