原创

go实现tcp网络编程

温馨提示:
本文最后更新于 2022年01月19日,已超过 800 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

本文只做为go tcp编程入门参考

tcp服务端实现:

package tcp

import (
   "bufio"
   "fmt"
   "net"
)

//声明服务器启用状态,预留状态变量
var SERVER_STATUS int8 = STATUS_UN_START

//状态变量枚举
const (
   STATUS_UN_START            int8 = 0
   STATUS_START_START_ING     int8 = 1
   STATUS_START_START_SUCCESS int8 = 2
   STATUS_CLOSE               int8 = 3
)

//启动server
func StartServer(listenAddress string) {
   //将状态更新为正在启动
   SERVER_STATUS = STATUS_START_START_ING
   //监听tcp协议
   listen, err := net.Listen("tcp", listenAddress)
   if err != nil {
      fmt.Println("listen failed,err:", err)
   }
   fmt.Println("tcp listen success.")
   //将状态改为启动成功
   SERVER_STATUS = STATUS_START_START_SUCCESS
   defer func() {
      //如果发生了异常,则直接关闭服务
      SERVER_STATUS = STATUS_CLOSE
      _ = listen.Close()
   }()
   for {
      //关闭监听
      //如果全局变量变为已关闭,则退出循环
      if SERVER_STATUS == STATUS_CLOSE {
         break
      }
      //接收客户端连接
      conn, err := listen.Accept()
      if err != nil {
         fmt.Println("accept failed,err:", err)
         continue
      }
      //新开协程处理客户端数据
      go tcpProcess(conn)
   }
}

func tcpProcess(conn net.Conn) {
   //如果发生异常或者结束栈,则关闭此连接
   defer func() {
      conn.Close()
   }()

   for true {
      //关闭监听
      if SERVER_STATUS == STATUS_CLOSE {
         break
      }
      //读取数据
      reader := bufio.NewReader(conn)
      //声明一个二进制数组
      var buf [128]byte
      //读取
      n, err := reader.Read(buf[:])
      if err != nil {
         fmt.Println("read from client failed,err:", err)
         return
      }
      //将二进制数据转为string
      recvStr := string(buf[:n])
      fmt.Println("收到client端发来的数据:", recvStr)
      //发送数据到客户端
      conn.Write([]byte("已收到数据"))
   }
}

调用:

package main

import (
   "testProject/tcp"
   "fmt"
   "sync"
)

var wg sync.WaitGroup

func main() {
   address := "127.0.0.1:9999"
   //+1
   wg.Add(1)
   go func() {
      tcp.StartServer(address)
      //只有tcp结束之后,才会走到这,-1
      wg.Done()
   }()
   //main协程阻塞,直到server结束
   wg.Wait()
   fmt.Println("进程结束")
}

输出:

仙士可博客

tcp客户端

package tcp

import (
   "bufio"
   "fmt"
   "net"
   "os"
   "strings"
)

//连接服务器
func ConnectServer(address string) {
   conn, err := net.Dial("tcp", address)
   if err != nil {
      fmt.Println("connect server failed:", err)
      return
   }
   fmt.Println("tcp client connect success.")
   //如果结束栈,则关闭此连接
   defer func() {
      conn.Close()
   }()
   //声明从标准输入读取数据
   inputReader := bufio.NewReader(os.Stdin)
   for true {
      fmt.Println("请输入需要发送的数据")
      //读到\n符号则返回数据
      input, _ := inputReader.ReadString('\n')
      //去除\r\n
      inputInfo := strings.Trim(input, "\r\n")
      //如果接收到quit,则退出此客户端
      if strings.ToLower(inputInfo) == "quit" {
         return
      }
      //将读取到的数据发送到服务端
      _, err = conn.Write([]byte(inputInfo))
      if err != nil {
         return
      }
      buf := [128]byte{}
      //从服务端读取数据
      n, err := conn.Read(buf[:])
      if err != nil {
         fmt.Println("recv failed,err:", err)
         return
      }
      fmt.Println("tcp client 收到数据:", string(buf[:n]))
   }
}

调用:

package main

import "testProject/tcp"

func main() {
   address := "127.0.0.1:9999"
   tcp.ConnectServer(address)
}

调用结果:

仙士可博客

正文到此结束
本文目录