对tcp连接部分以及与连接绑定的业务部分进行抽象和封装
主要是对连接的开启关闭和读写进行封装,抽象出接口,使用回调进行具体业务的绑定
zinterface/iconnection.go
package zinterface import "net" type IConnection interface{ Start() Stop() GetConnId() uint32 IsClosed() bool Send(data []byte,len int) error GetRemoteAddr() net.Addr GetConn() *net.TCPConn } type HandleFunc func (*net.TCPConn,[]byte,int) error
znet/connection.go
package znet import ( "log" "net" "zinx/zinterface" ) type Connection struct { ConnId uint32 Conn *net.TCPConn Closed bool RemoteAddr net.Addr ExitChan chan bool HandleAPI zinterface.HandleFunc } func NewConnection(connid uint32, conn *net.TCPConn, callback zinterface.HandleFunc) zinterface.IConnection { c := &Connection{ ConnId: connid, Conn: conn, Closed: false, ExitChan: make(chan bool, 1), HandleAPI: callback, } return c } func (c *Connection) StartRead() { defer c.Stop() for { b := make([]byte, 512) len, err := c.Conn.Read(b) if err != nil { log.Println("read tcp err ", err) break } log.Printf("recv from client %s,len=%d,connid=%d", b, len,c.ConnId) if err:=c.HandleAPI(c.Conn,b,len);err!=nil{ log.Println("c.handleAPI err ",err) break } } } func (c *Connection) Start() { go c.StartRead() } func (c *Connection) Stop() { if c.Closed { return } c.Closed = true c.Conn.Close() close(c.ExitChan) } func (c *Connection) GetConnId() uint32 { return c.ConnId } func (c *Connection) Send(data []byte, len int) error { return nil } func (c *Connection) GetRemoteAddr() net.Addr { return c.Conn.RemoteAddr() } func (c *Connection) GetConn() *net.TCPConn { return c.Conn } func (c *Connection) IsClosed() bool { return c.Closed }
znet/server.go
package znet import ( "fmt" "errors" "log" "net" "zinx/zinterface" ) type Server struct { Name string IP string IPversion string Port int } func Callbackapi(conn *net.TCPConn,readData []byte,len int) error{ if _, err := conn.Write(readData[:len]); err != nil { log.Println("write tcp err ", err) return errors.New("write tcp err") } log.Println("callback write...") return nil } func (s *Server) Start() { log.Printf("%s %s:%d start... ", s.Name, s.IP, s.Port) go func() { addr, err := net.ResolveTCPAddr(s.IPversion, fmt.Sprintf("%s:%d", s.IP, s.Port)) if err != nil { log.Println("resolve tcp addr err ", err) return } listener, err := net.ListenTCP(s.IPversion, addr) if err != nil { log.Println("listen tcp err ", err) return } var connid uint32 connid=0 for { conn, err := listener.AcceptTCP() if err != nil { log.Println("accept tcp err ", err) continue } dealConn:=NewConnection(connid,conn,Callbackapi) go dealConn.Start() connid++ } }() } func (s *Server) Stop() { } func (s *Server) Server() { s.Start() select {} } func NewServer(name string) zinterface.IServer { s := &Server{ Name: name, IP: "0.0.0.0", IPversion: "tcp4", Port: 8999, } return s }