Skip to content

我在用kcp实现p2p时 发现会阻塞Write #298

@yl32940

Description

@yl32940

type P2PKCPConn struct {
peers *Map.SyncMap[string, net.Conn] // 保存的连接池
localDial net.Conn // 本地连接
listener *net.UDPConn // KCP监听器
revChan chan []byte // 接收通道
}

func Dial(raddr string) (net.Conn, error) {
udpaddr, err := net.ResolveUDPAddr("udp", raddr)
if err != nil {
return nil, errors.WithStack(err)
}
network := "udp4"
if udpaddr.IP.To4() == nil {
network = "udp"
}

conn, err := net.ListenUDP(network, nil)
if err != nil {
	return nil, errors.WithStack(err)
}
conn.SetWriteBuffer(1024 * 1024 * 5) // 5MB 缓冲区
conn.SetReadBuffer(1024 * 1024 * 5)  // 5MB 缓冲区
session, err := kcp.NewConn(raddr, nil, 0, 0, conn)

listener := &P2PKCPConn{
	listener:  conn,
	localDial: session,
	peers:     Map.NewSyncMap[string, net.Conn](),
	revChan:   make(chan []byte),
}
println("监听地址:", listener.LocalAddr().String())
go listener.receiveLoop(session, true)
return listener, nil

}

func (p *P2PKCPConn) Write(b []byte) (n int, err error) {
p.localDial.SetWriteDeadline(time.Now().Add(time.Second * 10))
n, err = p.localDial.Write(b)
p.localDial.SetWriteDeadline(time.Time{})
return
}
func (p *P2PKCPConn) WriteTo(b []byte, addr string) (n int, err error) {
if conn, ok := p.peers.Get(addr); ok {
return conn.Write(b)
}

session, err := kcp.NewConn(addr, nil, 0, 0, p.listener)
p.peers.Set(addr, session)
go p.receiveLoop(session, false)
session.SetWriteDeadline(time.Now().Add(time.Second * 1))

return session.Write(b)

}

func (p *P2PKCPConn) Read(b []byte) (n int, err error) {
buf := <-p.revChan
copy(b, buf)
return len(buf), nil
//return p.localDial.Read(b)

}

这里的 localDial 是专门连接服务器用于获取 p2p 所需要连接的地址 我通过 WriteTo 去发起p2p连接 但是我发现这样会导致 Write 阻塞 如何避免这种情况 或者 有没有其他办法实现 p2p 用 kcp

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions