func (p *TUDPTransport) Read(buf []byte) (int, error) {
	if !p.IsOpen() {
		return 0, thrift.NewTTransportException(thrift.NOT_OPEN, "Connection not open")
	}
	n, err := p.conn.Read(buf)
	return n, thrift.NewTTransportExceptionFromError(err)
}
Read reads one UDP packet and puts it in the specified buf
package transport
import (
	"bytes"
	"context"
	"errors"
	"net"
	"sync/atomic"
	"github.com/apache/thrift/lib/go/thrift"
)
const MaxLength = 65000
var errConnAlreadyClosed = errors.New("connection already closed")
type TUDPTransport struct {
	conn     *net.UDPConn
	addr     net.Addr
	writeBuf bytes.Buffer
	closed   uint32  
}
func NewTUDPClientTransport(destHostPort string, locHostPort string) (*TUDPTransport, error) {
	destAddr, err := net.ResolveUDPAddr("udp", destHostPort)
	if err != nil {
		return nil, thrift.NewTTransportException(thrift.NOT_OPEN, err.Error())
	}
	var locAddr *net.UDPAddr
	if locHostPort != "" {
		locAddr, err = net.ResolveUDPAddr("udp", locHostPort)
		if err != nil {
			return nil, thrift.NewTTransportException(thrift.NOT_OPEN, err.Error())
		}
	}
	return createClient(destAddr, locAddr)
}
func createClient(destAddr, locAddr *net.UDPAddr) (*TUDPTransport, error) {
	conn, err := net.DialUDP(destAddr.Network(), locAddr, destAddr)
	if err != nil {
		return nil, thrift.NewTTransportException(thrift.NOT_OPEN, err.Error())
	}
	return &TUDPTransport{addr: destAddr, conn: conn}, nil
}
func NewTUDPServerTransport(hostPort string) (*TUDPTransport, error) {
	addr, err := net.ResolveUDPAddr("udp", hostPort)
	if err != nil {
		return nil, thrift.NewTTransportException(thrift.NOT_OPEN, err.Error())
	}
	conn, err := net.ListenUDP(addr.Network(), addr)
	if err != nil {
		return nil, thrift.NewTTransportException(thrift.NOT_OPEN, err.Error())
	}
	return &TUDPTransport{addr: conn.LocalAddr(), conn: conn}, nil
}
func (p *TUDPTransport) Open() error {
	return nil
}
func (p *TUDPTransport) Conn() *net.UDPConn {
	return p.conn
}
func (p *TUDPTransport) IsOpen() bool {
	return atomic.LoadUint32(&p.closed) == 0
}
func (p *TUDPTransport) Close() error {
	if atomic.CompareAndSwapUint32(&p.closed, 0, 1) {
		return p.conn.Close()
	}
	return errConnAlreadyClosed
}
func (p *TUDPTransport) Addr() net.Addr {
	return p.addr
}