xtaci / smux

A Stream Multiplexing Library for golang with least memory usage(TDMA)
MIT License
1.31k stars 196 forks source link

session.IsClosed() has different behavior with yamux #59

Closed gonejack closed 4 years ago

gonejack commented 4 years ago

We are using session.IsClosed() for knowing the time to quit session listening with yamux.

After switching to smux session.IsClosed() is not true anymore as with yamux when client side actively close the session.

for {
    stream, err := session.AcceptStream()

    if err == nil {
        // do something
    } else {
        if session.IsClosed() { // this will be true when session.close() is called on client side in yamux, but not in smux.
            return
        } else {
            fmt.Printf("accept stream error %s", err)
            time.Sleep(time.Second)
        }
    }
}
xtaci commented 4 years ago

Yes, it's different. For smux, Session.IsClosed() is to test whether session has Closed by other goroutines in current system.

IsClosed() a test for resource de-allocation.

Think about int socket() function in C.

It's also not possible to check whether the socket has closed by remote, EXCEPT by checking the return values from int read() and int write() functions.

So, If you want to detect whether the remote has closed , then you can check the return value from stream.Read() , stream.Write() or session.AcceptStream()

There are 2 cases:

  1. The peer has closed smux.Session as well as the underlying net.Conn, then session.AcceptStream(), stream.Read() & stream.Write() will return error immediately.
  2. The peer has only closed smux.Session, but the underlying net.Conn has not closed, the remote won't respond. In this case, after smux.Config.KeepAliveTimeout, session will close itself.