[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, ),
HandleAPI: callback,
}
return c
}
func (c *Connection) StartRead() {
defer c.Stop()
for {
b := make([]byte, )
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=
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: ,
}
return s
}
[Go] 轻量服务器框架基础TCP连接的抽象和封装的更多相关文章
- [Go] 轻量服务器框架基础TCP服务模块
框架要先把整体的结构定义好,一般都是在$GOPATH目录的src下建立自己的目录 zinterface是一些接口的定义 znet就是接口的具体实现 IServer.go package zinterf ...
- [Go] 轻量服务器框架tcp的粘包问题 封包与拆包
tcp传输的数据是以流的形式传输的,因此就没有办法判断到哪里结束算是自己的一个消息,这样就会出现粘包问题,多个包粘在一起了 可以使用这样一个自定义的形式来解决,一个消息分为 head+body he ...
- [Go] 轻量服务器框架全局配置的实现以及解析json
在一个应用中经常需要有一个配置文件,可以对代码中的参数进行配置,可以使用一个json文件来对应一个struct的对象,进行全局配置 建一个conf/zinx.json作为配置文件 { "Na ...
- 阿里云轻量服务器价格及轻量与ECS服务器区别比较
https://yq.aliyun.com/articles/221647 摘要: 阿里云轻量应用服务器价格表及介绍,关于轻量应用服务器和ECS服务器的性能对比 阿里云轻量应用服务器是阿里云新推出的服 ...
- 腾讯云轻量服务器通过Docker搭建外网可访问连接的redis5.x集群
总结记录/朱季谦 最近买了一台4核16的腾讯云轻量应用服务器,花了我快四百的大洋,打算搭建一堆docker组件集群,最先开始是通过docker搭建redis集群,计划使用三个端口,分别是7001,70 ...
- Android轻量缓存框架--ASimpleCache
[转] 大神真面目 稀土掘金,这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识.前端.后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过! ...
- Cardinal:一个用于移动项目开发的轻量 CSS 框架
Cardinal 是一个适用于移动项目的 CSS 框架,包含很多有用的默认样式.矢量字体.可重用的模块以及一个简单的响应式模块系统.Cardinal 提供了一种在多种移动设备上实现可伸缩的字体和布局的 ...
- mysql服务器,大量tcp连接状态TIME_WAIT
今天早上,java应用中发现too many open files,检查了下使用的连接数发现基本上在两三百左右,mysql打开的文件数也就几百左右,再看所有tcp连接,发现3306的连接有4000多, ...
- 阿里云轻量应用服务器——配置MySQL远程连接(踩坑,LAMP+CentOS)
说在前面 本文讲解清晰,从0开始 如不能用Navicat等数据库软件远程登陆,请先检查:安全>防火墙中 是否添加了MYSQL的3306端口(ECS服务器请检查 安全组)如未添加,先点右上角“添加 ...
随机推荐
- 【CSS】378- [译]44个 CSS 精选知识点
写在前面 一个周五的晚上,闲来无事整理下自己的 github(经常做收藏党),今天打算都过一遍,发现一个 star很高的项目,里面有大量的 CSS 片段,而且标题很诱人,然后又花了将近1个小时从头到尾 ...
- 【TS】358- 浅析 TypeScript 设计模式
点击上方"前端自习课"关注,学习起来~ 作者:DD菜 https://zhuanlan.zhihu.com/p/43283016 设计模式就是软件开发过程中形成的套路,就如同你在玩 ...
- 每周一练 之 数据结构与算法(LinkedList)
这是第三周的练习题,原本应该先发第二周的,因为周末的时候,我的母亲大人来看望她的宝贝儿子,哈哈,我得带她看看厦门这座美丽的城市呀. 这两天我抓紧整理下第二周的题目和答案,下面我把之前的也列出来: 1. ...
- JS系列:js节点
节点(node) 在html文档中出现的所有东西都是节点 元素节点(HTML标签) 文本节点(文字内容) 注释节点(注释内容) 文档节点(document) … 每一种类型的节点都会有一些属性区分自己 ...
- 第二次作业-titanic数据集练习
一.读入titanic.xlsx文件,按照教材示例步骤,完成数据清洗. titanic数据集包含11个特征,分别是: Survived:0代表死亡,1代表存活Pclass:乘客所持票类,有三种值(1, ...
- 用js写九九乘法表格,附带背景颜色
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- fastText训练word2vec并用于训练任务
最近测试OpenNRE,没有GPU服务器,bert的跑不动,于是考虑用word2vec,捡起fasttext 下载安装 先clone代码 git clone https://github.com/fa ...
- 商业分析BA:用户故事怎么拆?
什么是User Story其实我觉得要对User Story做一个定义还是挺难的.曾经的我以为,所谓User Story是User来讲述的Story.你看啊,User Story的编写范式:As a ...
- 面试连环炮系列(五):你们的项目为什么要用RabbitMQ
你们的项目为什么要用RabbitMQ? 消息队列的作用是系统解耦.同步改异步.请求消峰,举个下订单的例子: 前端获取用户订单信息,请求后端的订单创建接口.这个接口并不直接请求订单服务,而是首先生成唯一 ...
- Life is not supposed to be easy 。
对每个人而言,真正的职责只有一个: 找到自我.然后在心中坚守一生,全心全意,永不停息. 所有其他的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波逐流,是对内心的恐惧. 对婚姻,对房子的 ...