原创

go实现tcp网络编程

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

本文只做为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)
}

调用结果:

仙士可博客

正文到此结束
本文目录