smux icon indicating copy to clipboard operation
smux copied to clipboard

stream 关闭后,session.AcceptStream阻塞了

Open nelojass opened this issue 9 months ago • 6 comments

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包,但是这里一直阻塞的原因不太清楚

nelojass avatar Mar 14 '25 07:03 nelojass

我的client从stream中读到eof之后,已经关闭了stream,sess,以及对应的udpsession的conn,但是server那边的AcceptStream还是阻塞着的直到超时,这看起来应该与预期不符吧

nelojass avatar Mar 14 '25 08:03 nelojass

stream的FIN和session的关闭,是两回事。 没有session关闭的信号,底层连接关闭就视为session关闭。

xtaci avatar Mar 14 '25 08:03 xtaci

但是问题server的session的关闭由谁来触发,client已经关闭了session,但是server这边的session没有人去关闭它,server这边不可能在关闭一个stream的时候就把session关闭吧,那如果不关闭,这个session就会一直存在。问题是client关闭的session也没有告知server的session。 然后client关闭了kcp的session之后,下一个client也只会新建一个新的udpsession,那么在server那边的那个session就一直阻塞了。 所以server这边的smux.Session的关闭时机是什么

nelojass avatar Mar 14 '25 08:03 nelojass

被动关闭,AcceptStream读取net.Conn返回错误的时候。

xtaci avatar Mar 14 '25 08:03 xtaci

ok,这个就是我想表达的疑问,看起来这里只能超时关闭

nelojass avatar Mar 14 '25 08:03 nelojass

smux不负责管理底层链接,只负责使用。

xtaci avatar Mar 14 '25 09:03 xtaci