zoukankan      html  css  js  c++  java
  • [Go] 轻量服务器框架基础TCP连接的抽象和封装

    对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
    }
  • 相关阅读:
    小总结下iphone开发环境搭建过程!
    Raspberry Pi之旅 【序】
    linux虚拟机中配置samba的实现文件共享的方法
    编写高质量的代码1尽量使用StringBuilder
    ArcEngine开发点滴1
    开源Firebird .NET Provider V0.9.0.0发布
    .NET的Ant构建系统 NAnt 0.91发布!
    iis7.5 发布rest服务,put请求返回404错误 解决方法
    COM学习笔记(1)
    2004年南京美食地图 [转载]
  • 原文地址:https://www.cnblogs.com/taoshihan/p/12044624.html
Copyright © 2011-2022 走看看