本篇文章主要介绍 Go 标准库中的 net 包,通过一个小例子介绍常用的 net 包函数/方法 Listen,Accept 和 Dial 等。

1. net 简介

Go 官网对 net 包的定义如下:

Package net provides a portable interface for network I/O, including TCP/IP, UDP, domain name resolution, and Unix domain sockets.

net 包的常用方法有 Listen, Accept 和 Dial 等。下面通过一段代码将他们组合起来:

package main

import (
"fmt"
"net"
"sync"
) var wg sync.WaitGroup func serverAccept(l net.Listener) {
defer wg.Done()
ln, err := l.Accept()
if err != nil {
fmt.Printf("accept error")
return
} recData := make([]byte, 1024)
len, err := ln.Read(recData) fmt.Printf("len: %d\n", len)
fmt.Printf("rec Data: %v\n", string(recData[:len])) sendData := []byte("hello, client")
ln.Write(sendData)
} func main() {
// server emulator
l, err := net.Listen("tcp", ":0")
if err != nil {
fmt.Printf("listen error")
return
} wg.Add(1)
go serverAccept(l) // client emulator
addr := l.Addr().String()
cn, err := net.Dial("tcp", addr)
if err != nil {
fmt.Printf("Dial error")
return
} data := []byte("hello, server")
cn.Write(data) recDataClient := make([]byte, 1024)
len, err := cn.Read(recDataClient)
fmt.Printf("recDataClient: %v", string(recDataClient[:len])) wg.Wait()
}

这段代码实现了一个 server emulator 和 client emulator,client 发送 hello, server 给 server,server 再返回 hello, client 给 client。查看代码执行结果:

len: 13
rec Data: hello, server
recDataClient: hello, client

下面介绍代码使用到的 net 包函数/方法。

1.1 net.Listen

调用 Listen 将使 server 侦听在网络地址上。Listen 是 net 包中的函数,它的输入是 network 和 address,返回值是接口类型 Listener:

func Listen(network, address string) (Listener, error) {
var lc ListenConfig
return lc.Listen(context.Background(), network, address)
}

查看 Listener 的定义:

type Listener interface {
// Accept waits for and returns the next connection to the listener.
Accept() (Conn, error) // Close closes the listener.
// Any blocked Accept operations will be unblocked and return errors.
Close() error // Addr returns the listener's network address.
Addr() Addr
}

它包括三种方法 Accept,Close 以及 Addr。查看 Accept 方法如下:

1.2 Listener.Accept

查看官网对 Accept 方法的定义:

Accept implements the Accept method in the Listener interface; it waits for the next call and returns a generic Conn.

它有两种原型:

func (l *TCPListener) Accept() (Conn, error)

func (l *UnixListener) Accept() (Conn, error)

Accept 的指针接收者为 TCPListener,代码中调用 Accept 的是接口类型 Listener。所以应该发生了 TCPListener 到接口类型的转换,转换过程就发生在 lc.Listen(...) 函数里,查看该函数:

func (lc *ListenConfig) Listen(ctx context.Context, network, address string) (Listener, error) {
...
var l Listener
la := addrs.first(isIPv4)
switch la := la.(type) {
case *TCPAddr:
l, err = sl.listenTCP(ctx, la)
case *UnixAddr:
l, err = sl.listenUnix(ctx, la)
...
} func (sl *sysListener) listenTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) {
...
}

发现方法 listenTCP,listenUnix 做了接口类型的转换。

1.3 net.Dial

client 调用 Dial 函数和 server 建立连接,Dial 返回 Conn 接口类型。

func Dial(network, address string) (Conn, error) {
var d Dialer
return d.Dial(network, address)
}

1.4 Conn

Conn 是一种接口类型,查看它的定义:

type Conn interface {
// Read reads data from the connection.
// Read can be made to time out and return an error after a fixed
// time limit; see SetDeadline and SetReadDeadline.
Read(b []byte) (n int, err error) // Write writes data to the connection.
// Write can be made to time out and return an error after a fixed
// time limit; see SetDeadline and SetWriteDeadline.
Write(b []byte) (n int, err error) // Close closes the connection.
// Any blocked Read or Write operations will be unblocked and return errors.
Close() error LocalAddr() Addr RemoteAddr() Addr SetDeadline(t time.Time) error SetReadDeadline(t time.Time) error SetWriteDeadline(t time.Time) error
}

代码中使用到了接口的 Read 和 Write 方法,它的功能如注释所示。其中 Read 和 Write 的入参是字节切片。

1.5 字节切片 []byte

Go 中定义了字节切片,字符切片的特性如下:

  1. 一个字符串是一个不可改变的字节序列
  2. 文本字符串通常被解释为采用UTF8编码的Unicode码点(rune)序列
  3. 内置的len函数可以返回一个字符串中的字节数目
  4. 第i个字节并不一定是字符串的第i个字符,因为对于非ASCII字符的UTF8编码会要两个或多个字节
  5. 字符串操作基于原始字符串字节
  6. 字符串面值方式编写,只要将一系列字节序列包含在双引号内即可,解释字符串,其中的相关的转义字符将被替换;反引号括起来,支持换行,非解释字符串
  7. 每个符号都分配一个唯一的Unicode码点,Unicode码点对应Go语言中的rune整数类型
  8. UTF8是一个将Unicode码点编码为字节序列的变长编码
  9. 变长的编码无法直接通过索引来访问第n个字符
  10. 将字符串看作是字节(byte)的切片(slice)来实现对其标准索引法的操作

参考: https://cloud.tencent.com/developer/article/1501644

Go 标准库 net的更多相关文章

  1. Python标准库--typing

    作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 1 模块简介 Python 3.5 增加了一个有意思的库--typ ...

  2. PHP SPL(PHP 标准库)

    一.什么是SPL? SPL是用于解决典型问题(standard problems)的一组接口与类的集合.(出自:http://php.net/manual/zh/intro.spl.php) SPL, ...

  3. C 标准库系列之locale.h

    locale.h 区域设置相关,主要针对时间日期.货币格式.字符控制.数字格式等以满足某区域的设置需要. locale设置类别主要包括以下几个宏定义的类别: LC_ALL:设置所有的类别: LC_CO ...

  4. C 标准库系列之errno.h

    errno.h 提供了一个整数全局变量errno,当系统调用或者库函数的错误事件发生时可能会修改该值,指明错误的原因,该值可在任何需要的地方被修改:一般情况不为0的值表示出现了异常或者错误. errn ...

  5. C 标准库系列之assert.h

    先简单介绍一下<assert.h>头文件,该头文件的目的便是提供一个宏assert的定义,即可以在程序必要的地方使用其进行断言处理:断言在程序中的作用是当在调试模式下时,若程序给出的前提条 ...

  6. C 标准库系列之概述

    基本上很多编程语言都会提供针对语言本身的一系列的标准库或者包,当然C语言同样也有提供标准库,C语言的标准库是一系列的头文件的集合:如assert.h.ctype.h.errno.h.float.h.l ...

  7. C标准库-数值字符串转换与内存分配函数

    原文链接:http://www.orlion.ga/977/ 一.数值字符串转换函数 #include <stdlib.h> int atoi(const char *nptr); dou ...

  8. Python标准库13 循环器 (itertools)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在循环对象和函数对象中,我们了解了循环器(iterator)的功能.循环器是对象的 ...

  9. Python标准库14 数据库 (sqlite3)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Python自带一个轻量级的关系型数据库SQLite.这一数据库使用SQL语言.S ...

  10. 把《c++ primer》读薄(3-3 标准库bitset类型)

    督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. //开头 #include <bitset> using std::bitset; 问题1.标准库bitset类型( ...

随机推荐

  1. erp——绩效考核系统——数据需求说明书

    绩效考核--数据需求说明书 1.引言 1.1编写目的 数据要求说明书详细的提供了系统中各个数据的流向,是设计数据库的关键所在,为以后的编码以及测试提供一份可靠的依据. 1.2 对象 本<数据要求 ...

  2. Tensorflow2.0实战之Auto-Encoder

    autoencoder可以用于数据压缩.降维,预训练神经网络,生成数据等等 Auto-Encoder架构 需要完成的工作 需要完成Encoder和Decoder的训练 例如,Mnist的一张图片大小为 ...

  3. Pix4Dmapper空间三维模型的应用实例:GIS选址分析

      本文介绍基于无人机影像建模完成后的结果,利用ArcMap软件进行空间选址分析,从而实现空间三维模型应用的方法. 目录 1 空间分析目标确立 2 基于基本约束条件的选址求解 2.1 坡度计算与提取 ...

  4. 数字孪生结合GIS会为智慧农业带来怎样的改变?

    数字孪生是一种创新的技术,它通过将现实世界的物理实体与数字模型相结合,实现了实时.动态的仿真和预测.而地理信息系统(GIS)则是一种用于收集.管理.分析和展示地理数据的工具.当这两种技术相互融合时,将 ...

  5. 数字孪生和GIS融合后能够为城市交通带来哪些便利?

    数字孪生和GIS的融合对于城市交通领域带来了诸多便利,从智能交通管理到出行体验的提升,为城市交通带来了全新的发展机遇. 首先,数字孪生技术与GIS的结合可以实现智能交通管理.通过GIS建立城市交通网络 ...

  6. 云MSP技本功|redis的5种对象与8种数据结构之字符串对象(下)

    简介: 引言 本文是对<redis设计与实现(第二版)>中数据结构与对象相关内容的整理与说明.本篇文章只对对象结构,1种对象--字符串对象.以及字符串对象所对应的两种编码--raw和emb ...

  7. Ubuntu 23.04、22.04、20.04、18.04替换国内源

    Ubuntu配置国内源 配置步骤如下: 1.Ubuntu配置文件位置:/etc/apt/sources.list 2.需要用root权限进入: sudo vi /etc/apt/sources.lis ...

  8. 聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(二)

    聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(二) 前言 前文排版比较糟糕,这次我们使用vscode来写本文,,各位看客请见谅 ...

  9. Spring表达式语言(SPEL)学习(03)

    rootObject 在表达式中直接写name和getName(),这时候Expression是无法解析的,因为其不知道name和getName()对应什么意思 @Test public void t ...

  10. grpc双向流究竟是什么情况?2段代码告诉你

    摘要:为什么需要grpc双向流? 本文分享自华为云社区<grpc双向流究竟是什么情况?2段代码告诉你>,作者:breakDawn. 为什么需要grpc双向流? 有时候请求调用和返回过程,并 ...