golang 使用 net包实现 tcp server 示例

之前用到 golang 进行网络编程时,主要就是使用 net/httpweb 框架 gin,这些网络库的底层其实也还是用的标准库自带的 net包,很多是对路由或者其他做封装,而且 golang 本身的长处之一也是网络IO的处理,这也得益于其底层的 IO模型,今天我们分享的是基于 TCP server/client 的简单实现,后面将分享相关源码分析。

TCP server,显然这在网络模型中属于四层模型,指的是最终通过 tcp协议 进行通信,http server 则是再其之上的封装,按照 tcp socket 的连接建立流程,我们可以分为以下:

server:

  • bind
  • listen
  • accept
  • read/write
  • close

client:

  • connect
  • write/read
  • close

golang 中,利用 协程 我们可以便捷地对每个连接开启新的协程进行处理,达到并发处理的效果。

接下来看看相关的 server、client 的简单实现吧。

server

package main

import (
	"fmt"
	"net"
)

func main()  {
	lis, err := net.Listen("tcp", ":8000")
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println("server is up now...")
	for {
		conn, err := lis.Accept()
		if err != nil {
			fmt.Println(err)
			return
		}
		clientAddr := conn.RemoteAddr()
		fmt.Printf("recv client [%s] connection...\n", clientAddr)
		go serve(conn)
	}
}

func serve(conn net.Conn)  {
	defer conn.Close()
	buf := make([]byte, 64)
	n, _ := conn.Read(buf)
	conn.Write([]byte("pong: "))
	conn.Write(buf[:n])
}

在代码中,我们首先通过 net.Listen() 创建 server 监听对象,接着通过 loop 对每个客户端连接都新建 goroutine 进行处理。

client

package main

import (
	"fmt"
	"net"
)

func main()  {
	conn, err := net.Dial("tcp", ":8000")
	if err != nil {
		panic(err)
	}
	conn.Write([]byte("hello world\n"))
	i := 0
	buf := make([]byte, 128)
	for i < 2 {
		n, _ := conn.Read(buf)
		fmt.Println(string(buf[:n]))
		i++
	}
}

client 也很简单,只需要通过 net.Dial 即可创建一个连接,然后进行通信。

代码实现简单,但作为 coder,还是要了解更要理解 golang 的网络编程实现原理,比如为何 golang 简单的 server 就可以实现 高并发,内部是怎么实现的呢,后面我们将继续分享。

posted on 2023-04-26 10:10  进击的davis  阅读(231)  评论(0编辑  收藏  举报

导航