Skip to main content

[tcp] TCP 网络连接库

本网络连接库经过高度简化,并不使用传统 Socket 接口,而使用核心的三个函数来完成常见 TCP 的功能

  1. Connect 作为 TCP 连接客户端发起连接
  2. Serve 快速构建一个 TCP 服务器
  3. Forward 端口转发,可以把一个本地端口的流量转发到远程端口上

一个例子看透 TCP 库的三个 API#

// 设置日志的级别,方便我们看到 TCP 库的一些信息输出loglevel("info")
// 启动一个 TCP 服务器,在 Goroutine 中异步启动go fn{    tcp.Serve("127.0.0.1", 8085, tcp.serverCallback(func(conn) {        println("真正的 TCP 服务器收到一个连接:", conn.RemoteAddr())        bytes, err := conn.RecvLen(4)        if err != nil {            conn.Close()            return        }        println("收到连接的前 4 个字符为", string(bytes))        println("发送一个 Hello World 给客户端")
        conn.Send("你好,世界!Hello World from 127.0.0.1:8085")        println("发送成功了!")        conn.Close()    }))}
// 启动一个 TCP 本地转发,把本地 9000 转发到 127.0.0.1:8085go fn{    tcp.Forward(9000, "127.0.0.1", 8085)}
// 启动一个 TCP 连接,直接访问本地 9000 端口conn, err := tcp.Connect("127.0.0.1", 9000)die(err)
// 发送一个消息给 9000 端口conn.Send("abdasdf this message from client")
dump(conn.RecvStringTimeout(1))// 等待3秒观察日志sleep(3)

上面的脚本其实非常直观:

  1. 我们启动了 TCP 服务器
  2. 把 TCP 服务器的端口做了转发,转发到 9000 端口上了
  3. 然后我们访问本地 9000 端口,发送一条消息
  4. 我们从客户端收到了,服务器返回来的消息
[INFO] 2021-06-11 17:52:47 +0800 [default:tcp_serve.go:63] recv tcp connection from 127.0.0.1:58352 to 127.0.0.1:9000[INFO] 2021-06-11 17:52:47 +0800 [default:tcp_util.go:15] recv local connection from: 127.0.0.1:58352[INFO] 2021-06-11 17:52:47 +0800 [default:tcp_serve.go:63] recv tcp connection from 127.0.0.1:58353 to 127.0.0.1:8085[INFO] 2021-06-11 17:52:47 +0800 [default:tcp_util.go:23] create remote connection from: 127.0.0.1:8085真正的 TCP 服务器收到一个连接: 127.0.0.1:58353收到连接的前 4 个字符为 abda发送一个 Hello World 给客户端发送成功了!([]interface {}) (len=2 cap=2) { (string) (len=49) "你好,世界!Hello World from 127.0.0.1:8085", (interface {}) <nil>}

详细 API 介绍#

  1. fn tcp.Connect(host: string, port: int, params: ...clientParams): (*yaklib.tcpConnection, error) 发起一个 TCP 连接
  2. fn tcp.Forward(localPort: int, remoteHost: string, remotePort: int): error 转发一个 TCP 连接(把一个远程连接映射到本地)
  3. fn tcp.Serve(var_1: interface {}, var_2: int, vars: ...yaklib.tcpServerConfigOpt): error 启动一个 TCP 服务器

TCP 客户端参数#

  1. fn tcp.clientLocal(var_1: interface {}): yaklib.dialerOpt 客户端参数,设置本地地址
  2. fn tcp.clientTimeout(var_1: float64): yaklib.dialerOpt 客户端参数,当次连接的超时时间
  3. fn tcp.clientTls(var_1: interface {}, var_2: interface {}, vars: ...interface {}): yaklib.tcpServerConfigOpt 开启 TLS 加密的 TCP 连接

TCP 服务端参数#

  1. fn tcp.serverCallback(var_1: func(*yaklib.tcpConnection)): yaklib.tcpServerConfigOpt 服务端参数:设置回调函数,处理服务器端收到的 TCP 连接
  2. fn tcp.serverContext(var_1: context.Context): yaklib.tcpServerConfigOpt 服务器端参数,设置超时时间
  3. fn tcp.serverTls(cert: interface {}, privateKey: interface {}, caCerts: ...interface {}): yaklib.tcpServerConfigOpt 为服务器设置 TLS,设置一个加密的 TLS

结构定义#

*yaklib.tcpConnection 函数定义#

type palm/common/yak/yaklib.(tcpConnection) struct {  Fields(可用字段):      Conn: net.Conn  StructMethods(结构方法/函数):      // 关闭网络连接      func Close() return(error)
      // 查看本地地址      func LocalAddr() return(net.Addr)
      // 标准 Read 接口      func Read(v1: []uint8) return(int, error)
      // 远程地址      func RemoteAddr() return(net.Addr)
      // 设置读写 DDL      func SetDeadline(v1: time.Time) return(error)      func SetReadDeadline(v1: time.Time) return(error)      func SetWriteDeadline(v1: time.Time) return(error)
      // 标准写接口      func Write(v1: []uint8) return(int, error)  PtrStructMethods(指针结构方法/函数):      func Close() return(error)      func GetTimeout() return(time.Duration)      func LocalAddr() return(net.Addr)      func Read(v1: []uint8) return(int, error)
      // 接收 bytes,会阻塞      func Recv() return([]uint8, error)
      // 接收固定长度的 bytes      func RecvLen(v1: int64) return([]uint8, error)
      // 接收一个字符串      func RecvString() return(string, error)
      // 接收一个字符串,如果超时就直接返回      func RecvStringTimeout(v1: float64) return(string, error)
      // 接收一个 bytes,超时返回      func RecvTimeout(v1: float64) return([]uint8, error)
      // 远程地址      func RemoteAddr() return(net.Addr)
      // 发送一个对象,这个对象不同类型会有不同操作,json      func Send(v1: interface {}) return(error)
      // 设置 DDL      func SetDeadline(v1: time.Time) return(error)      func SetReadDeadline(v1: time.Time) return(error)      func SetWriteDeadline(v1: time.Time) return(error)
      // 标准写      func Write(v1: []uint8) return(int, error)            // 设置默认超时      func SetTimeout(v1: float64)
}