基础的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

  1. 直接连接远程服务器,得到一个conn连接 net.Dial
  2. 连接调用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)
}

随机推荐

  1. mariadb5.5.56二进制离线安装

    在生产环境中一般使用发布好的二进制版本,简单概括一下安装过程: 1. 下载 地址为:https://downloads.mariadb.org/mariadb/5.5.56/ 这里选择最新版本的5.5 ...

  2. MAC地址格式详解

    以太网编址 在数据链路层,数据帧通常依赖于MAC地址来进行数据交换,它如同公网IP地址一样要求具有全球唯一性,这样才可以识别每一台主机.那么MAC地址如何做到这点?它的格式又是什么? MAC地址,英文 ...

  3. docker安装cdh6.3.2集群(联网版)

    一.前言 本次采用的在线安装方式,cdh为6.3.2版本,系统为centos7.4, docker节点可以为任意多个,下文将以3个docker容器为示例进行展示.此方法也可用在docker swarm ...

  4. tlmgr 操作

    宏包管理 sudo tlmgr install <package> # 安装宏包 sudo tlmgr install scheme-full # 安装全部宏包 sudo tlmgr re ...

  5. Prism:框架介绍与安装

    Prism:框架介绍与安装 什么是Prism? Prism是一个用于在 WPF.Xamarin Form.Uno 平台和 WinUI 中构建松散耦合.可维护和可测试的 XAML 应用程序框架 Gith ...

  6. 【Docker学习教程系列】8-如何将本地的Docker镜像发布到私服?

    通过前面的学习,我们已经知道,怎么将本地自己制作的镜像发布到阿里云远程镜像仓库中去.但是在实际工作开发中,一般,我们都是将公司的镜像发布到公司自己搭建的私服镜像仓库中,那么一个私服的镜像仓库怎么搭建? ...

  7. spark 自定义 accumulator

    默认的accumulator 只是最简单的 int/float 有时候我需要一个map来作为accumulator 这样,就可以处理 <string, int>类型的计数了. 此外我还需要 ...

  8. docker 修改容器内容后更新镜像的流程

    在 Docker 中,如果你修改了一个容器的内容并希望将这些更改保存为一个新的镜像,可以按照以下步骤进行: docker version: 26.1 1. 确保容器运行 首先,确保你正在修改的容器是运 ...

  9. 深度学习模型训练的过程理解(训练集、验证集、测试集、batch、iteration、epoch、单步预测、多步预测、kernels、学习率)

    呜呜呜呜,感谢大佬学弟给我讲干货. 本来是讨论项目的,后面就跑偏讲论文模型了. 解答了我一直以来的疑问: 数据放模型里训练的过程. 假设我们有一个数据集26304条数据,假设设置模型读入1000条,如 ...

  10. Angular 18+ 高级教程 – Dependency Injection 依赖注入

    前言 本来是想先介绍 Angular Component 的,但 Component 里面会涉及到一些 Dependency Injection (简称 DI) 的概念,所以还是先介绍 DI 吧. 温 ...