| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- package NetUtils
- import (
- "bufio"
- "encoding/binary"
- "errors"
- "github.com/astaxie/beego/logs"
- "io"
- "net"
- "forward-core/Common"
- )
- func NewTCP(addr string) (net.Listener, error) {
- tcpSocket, err := net.Listen("tcp", addr)
- if err != nil {
- return nil, err
- }
- return tcpSocket,nil
- }
- func NewUDP(addr string) (*net.UDPConn, error) {
- udpAddr, err := net.ResolveUDPAddr("udp", addr)
- if err != nil {
- return nil, err
- }
- udpSocket, _err := net.ListenUDP("udp", udpAddr)
- if _err != nil {
- return nil, _err
- }
- return udpSocket,nil
- }
- func NewKCP(addr string, setting *Common.KcpSetting) (*Common.UDPListener, error) {
- return Common.NewKCP(addr, setting)
- }
- func DataCopy(dst io.Writer, src io.Reader) (written int64, err error) {
- return io.Copy(dst, src)
- }
- func MultiDataCopy(src io.Reader, dispatchConns []io.Writer) (written int64, err error) {
- mWriter := io.MultiWriter(dispatchConns...)
- return io.Copy(mWriter, src)
- }
- type ReadCallBack func(conn net.Conn, id int, cmd byte, arg []byte)
- func ReadConn(conn net.Conn, callback ReadCallBack) {
- scanner := bufio.NewScanner(conn)
- scanner.Split(func(data []byte, atEOF bool) (adv int, token []byte, err error) {
- return NetSplitV1(data, atEOF, conn, callback)
- })
- for scanner.Scan() {
- }
- if scanner.Err() != nil {
- logs.Error(scanner.Err())
- }
- }
- func NetSplitV1(data []byte, atEOF bool, conn net.Conn, callback ReadCallBack) (adv int, token []byte, err error) {
- l := len(data)
- if l < 6 {
- return 0, nil, nil
- }
- if l > 100000 {
- conn.Close()
- return 0, nil, errors.New("max data")
- }
- var id int
- var cmd byte
- id = int(int32(data[0]) | int32(data[1])<<8 | int32(data[2])<<16 | int32(data[3])<<24)
- cmd = data[4]
- isShort := data[5]
- var payload []byte
- var offset int
- if isShort == 1 {
- offset = 6
- } else {
- if l < 10 {
- return 0, nil, nil
- }
- ls := binary.LittleEndian.Uint32(data[6:])
- tail := l - 10
- if tail < int(ls) {
- return 0, nil, nil
- }
- payload = data[10 : 10+ls]
- offset = 10 + int(ls)
- }
- callback(conn, id, cmd, payload)
- return offset, []byte{}, nil
- }
- func WriteConn(conn net.Conn, id int, cmd byte, payload []byte) error {
- if conn == nil {
- return nil
- }
- l := len(payload)
- var buf []byte
- var size int
- if l > 0 {
- size = 10 + l
- //4+1+1+4 id cmd isShort
- buf = make([]byte, size)
- } else {
- size = 6
- //4+1+1 id cmd isShort
- buf = make([]byte, size)
- }
- buf[0] = byte(id)
- buf[1] = byte(id >> 8)
- buf[2] = byte(id >> 16)
- buf[3] = byte(id >> 24)
- buf[4] = cmd
- if l > 0 {
- buf[5] = 0
- binary.LittleEndian.PutUint32(buf[6:], uint32(l))
- copy(buf[10:], []byte(payload))
- } else {
- buf[5] = 1
- }
- _, err := conn.Write(buf[:size])
- if err != nil {
- logs.Error("conn.Write error:", err)
- }
- return err
- }
|