stream 关闭后,session.AcceptStream阻塞了
server部分代码
//conn为UDPSession
sess, err := smux.Server(conn, smuxConfig)
if err != nil {
log.Println("smux server err:", err)
return
}
//go func() {
defer func() {
sess.Close()
conn.Close()
}()
for {
stream, err := sess.AcceptStream()
if err != nil {
log.Println("sumx accept err:", err)
if err, ok := err.(net.Error); ok && err.Temporary() {
continue
}
break
}
go func() {
defer func() {
log.Printf("server end stream %08x:%d", conn.GetConv(), stream.ID())
stream.Close()
}()
log.Printf("server begin stream %08x:%d", conn.GetConv(), stream.ID())
SendOneKcpConnection(stream)
}()
}
sess创建自一个kcp.UdpSession: sess, err := smux.Server(conn, smuxConfig) 我的client和server都是已经关闭了stream的
但是我发现在关闭之后,AcceptStream一直阻塞知道smux超时才返回一个io: read/write on closed pipe 通过抓包我看到了smux确实已经互相发了fin包,但是这里一直阻塞的原因不太清楚
我的client从stream中读到eof之后,已经关闭了stream,sess,以及对应的udpsession的conn,但是server那边的AcceptStream还是阻塞着的直到超时,这看起来应该与预期不符吧
stream的FIN和session的关闭,是两回事。 没有session关闭的信号,底层连接关闭就视为session关闭。
但是问题server的session的关闭由谁来触发,client已经关闭了session,但是server这边的session没有人去关闭它,server这边不可能在关闭一个stream的时候就把session关闭吧,那如果不关闭,这个session就会一直存在。问题是client关闭的session也没有告知server的session。 然后client关闭了kcp的session之后,下一个client也只会新建一个新的udpsession,那么在server那边的那个session就一直阻塞了。 所以server这边的smux.Session的关闭时机是什么
被动关闭,AcceptStream读取net.Conn返回错误的时候。
ok,这个就是我想表达的疑问,看起来这里只能超时关闭
smux不负责管理底层链接,只负责使用。