func()

in client.go [178:230]


func (c *client) dialUDP() Session {
	var (
		err       error
		conn      *net.UDPConn
		localAddr *net.UDPAddr
		peerAddr  *net.UDPAddr
		length    int
		bufp      *[]byte
		buf       []byte
	)

	bufp = gxbytes.GetBytes(128)
	defer gxbytes.PutBytes(bufp)
	buf = *bufp
	localAddr = &net.UDPAddr{IP: net.IPv4zero, Port: 0}
	peerAddr, _ = net.ResolveUDPAddr("udp", c.addr)
	for {
		if c.IsClosed() {
			return nil
		}
		conn, err = net.DialUDP("udp", localAddr, peerAddr)
		if err == nil && gxnet.IsSameAddr(conn.RemoteAddr(), conn.LocalAddr()) {
			conn.Close()
			err = errSelfConnect
		}
		if err != nil {
			log.Warnf("net.DialTimeout(addr:%s, timeout:%v) = error:%+v", c.addr, perrors.WithStack(err))
			<-gxtime.After(connectInterval)
			continue
		}

		// check connection alive by write/read action
		conn.SetWriteDeadline(time.Now().Add(1e9))
		if length, err = conn.Write(connectPingPackage[:]); err != nil {
			conn.Close()
			log.Warnf("conn.Write(%s) = {length:%d, err:%+v}", string(connectPingPackage), length, perrors.WithStack(err))
			<-gxtime.After(connectInterval)
			continue
		}
		conn.SetReadDeadline(time.Now().Add(1e9))
		length, err = conn.Read(buf)
		if netErr, ok := perrors.Cause(err).(net.Error); ok && netErr.Timeout() {
			err = nil
		}
		if err != nil {
			log.Infof("conn{%#v}.Read() = {length:%d, err:%+v}", conn, length, perrors.WithStack(err))
			conn.Close()
			<-gxtime.After(connectInterval)
			continue
		}
		return newUDPSession(conn, c)
	}
}