对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...\n", 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
}