zinxV0.1
基础的server
框架
抽象层IServer.go
IServer.go
type IServer interface {
// 实现一个服务器的基本三个接口,启动,停止,入口
Start()
Stop()
Server()
}
实现层server.go
server.go
package znet
import (
"fmt"
"net"
)
type Server struct {
Name string
IP string
IpVersion string
Port int
}
// 实现IServer中的方法
func (s *Server) Start() {
}
func (s *Server) Stop() {
}
func (s *Server) Server() {
}
func NewServer(name string) ziface.IServer {
server := &Server{
Name: name,
IpVersion: "tcp4",
IP: "0.0.0.0",
Port: 8999,
}
return server
}
启动项目ZinxV0.1/Server.go
点击查看代码
func main() {
// 1. 创建一个server句柄,使用Zinx的api
s := znet.NewServer("[zinx V0.1]")
// 2. 启动server
s.Server()
}
方法
启动服务器
点击查看代码
func (s *Server) Start() {
fmt.Printf("[start] Server Listenner at IP : %s, Port: %d, is starting\n", s.IP, s.Port)
go func () {
// 1. 获取一个TCP的Addr net.ResolveTCPAddr
addr, err := net.ResolveTCPAddr(s.IpVersion, fmt.Sprintf("%s:%d", s.IP, s.Port))
if (err != nil) {
fmt.Println("resolve tcp addr error :", err)
return
}
// 2. 监听服务器的地址 net.ListenTCP
listenner, err := net.ListenTCP(s.IpVersion, addr)
if (err != nil) {
fmt.Println("listen", s.IpVersion, " err: ", err)
return
}
fmt.Println("start Zinx server succ, ", s.Name, "succ, Listenning")
// 3. 阻塞的等待客户端的连接,处理客户端连接业务(读写)
for {
// 如果有客户端连接过来,阻塞会返回 listenner.AcceptTCP()
conn, err := listenner.AcceptTCP()
if (err != nil) {
fmt.Println("Accept err", err)
continue
}
// 已经与客户端建立连接,做一些业务,做一个最基本的最大512字节长度的回显业务
go func() {
for {
buf := make([]byte, 512)
cnt, err := conn.Read(buf)
if (err != nil) {
fmt.Println("recv buf err", err)
continue
}
// 回显功能
if _, err := conn.Write(buf[:cnt]); err != nil {
fmt.Println("write back buf err", err)
continue
}
}
}()
}
}()
}
停止服务器
运行服务器
点击查看代码
func (s *Server) Server() {
s.Start()
// TODO 调用之后做阻塞处理,在之间可以做今后的扩展功能
select{}
}
初始化server
属性
name名称
监听的IP
监听的端口Port
IP版本IpVersion
基础的server
- 直接连接远程服务器,得到一个conn连接 net.Dial
- 连接调用Write写数据
点击查看代码
fmt.Println("client start...")
// 1. 直接连接远程服务器,得到一个conn连接 net.Dial
conn, err := net.Dial("tcp", "127.0.0.1:8999")
if (err != nil) {
fmt.Println("client start err, exit!")
return
}
for {
// 2.连接调用Write写数据
_, err := conn.Write([]byte("Hello Zinx V0.1.."))
if (err != nil) {
fmt.Println("write conn err", err)
return
}
buf := make([]byte, 512)
cnt, err := conn.Read(buf)
if (err != nil) {
fmt.Println("Read conn err", err)
return
}
fmt.Printf("server call back: %s, cnt = %d\n", buf, cnt)
// 阻塞cpu
time.Sleep(1 * time.Second)
}
随机推荐
- AndroidStudio 各种异常情况处理大法
最近使用AndroidStudio出现了.java文件,显示为xml文件等问题,通过各种采坑之后,发现删除本地的缓存文件这个方法最管用,差不多可以根治95%的莫名其妙的问题.解决办法如下: 先将AS关 ...
- lxml官方入门教程(The lxml.etree Tutorial)翻译
lxml官方入门教程(The lxml.etree Tutorial)翻译 说明: 首次发表日期:2024-09-05 官方教程链接: https://lxml.de/tutorial.html 使用 ...
- DatetimeFormatter字符串转日期
在Java中,我们经常需要将字符串形式的日期时间转换为LocalDateTime.LocalDate.LocalTime等日期时间对象,或者将日期时间对象转换为字符串.为了完成这些操作,我们可以使用D ...
- webpack 5.88.2
原理 webpack的运行过程大致可以分为以下几个步骤:webpack的运行过程实际上就是等待上一个钩子结束调用下一个钩子的过程 初始化:webpack接收命令行参数或配置文件,创建一个Compile ...
- [Tkey] 与非
解法原理1 首先我们需要明白 \(\operatorname{nand}\) 的运算: \[\operatorname{not}(a\operatorname{nand}b)=a\operatorna ...
- vue前端开发仿钉图系列(2)左侧图层列表的开发详解
项目开发前还是特别说明一下组件库的重要性,谢谢饿了么团队分享的element组件库,大大节省了页面的开发成本.左侧图层列表核心功能有1.根据图层类型展示点线面2.开关控制右侧地图上点线面的展示和隐藏3 ...
- threejs - 渲染第一个3D场景 - 旋转的正方体
1. 安装 threejs & 使用 2. 创建三要素 场景 scene 相机 camera 渲染器 render 3. 场景 new THREE.Scene() 相机分为 2 种 1. ...
- 我们在 vue 项目中如何做路由导航守卫
一般在 src 文件夹新建一个 permission 文件 ,单独用来做路由导航守卫业务 ,在 main.js 导入文件即可 : 主要功能有 判断是否有 token ,以此判断用户是不是登录了 :
- 01 如何具备编程思想(以 Python 举例)
博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https:// ...
- NOI 2024
Day1 T1 集合(set) 容易发现两个序列等价当且仅当,所有数字在序列中出现位置的集合构成集族相等. 考虑哈希,对于一个集合 \(S\),令它的哈希值为 \(f(S) = (\sum\limit ...