本篇文章主要介绍 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. 【UniApp】-uni-app-传递数据

    前言 好,经过上个章节的介绍完毕之后,了解了一下 uni-app-路由 那么了解完了uni-app-路由之后,这篇文章来给大家介绍一下 uni-app-路由传递数据 路由传参怎么传,是不是可以从 A ...

  2. LeetCode1806:还原排列的最少操作步数(置换群 or 模拟)

    题意:题目的意思是,给定一个初始状态perm,然后对perm的每个元素按照上述的规则进行变换操作.问:perm经过多少次这种操作能够变回初始的perm. 解题思路:第一种方法就是模拟,一直变换,直到变 ...

  3. 什么是革命性技术eBPF?为什么可观测性领域都得用它

    公众号「架构成长指南」,专注于生产实践.云原生.分布式系统.大数据技术分享. 如果有一种技术可以监控和采集任何应用信息,支持任何语言,并且应用完全无感知,零侵入,想想是不是很激动,那么这个技术是什么呢 ...

  4. 【电影推荐系统】Spring Boot + Vue3 前后端分离项目

    目录 0 前言 1 项目前端介绍 1.1 项目启动和编译 1.1.1 项目启动 1.1.2 项目编译 1.2 前端技术栈 1.3 功能模块前端界面展示 1.3.1 基础功能模块 1.3.2 用户模块 ...

  5. Windows下使用图形化的Havoc C2

    Windows下使用图形化的Havoc C2 前言 这几天用goland去连虚拟机去coding真的心累,想着搞个wsl算了虽然测试又变麻烦了(wsl2和VMware一起开有问题,可能保存不了快照), ...

  6. 【eBPF-03】进阶:BCC 框架中 BPF 映射的应用 v1.0

    eBPF 中实现内核态代码与用户态代码是可以实时通信的,这主要靠 BPF 映射 来实现. BPF 映射 是内核空间的一段内存,以 键值对 的方式存储.内核态程序可以直接访问 BPF 映射,用户态需要通 ...

  7. Redis 使用的 10 个小技巧

    Redis 在当前的技术社区里是非常热门的.从来自 Antirez 一个小小的个人项目到成为内存数据存储行业的标准,Redis已经走过了很长的一段路. 随之而来的一系列最佳实践,使得大多数人可以正确地 ...

  8. 【scikit-learn基础】--『监督学习』之 支持向量机分类

    支持向量机也是一种既可以处理分类问题,也可以处理回归问题的算法.关于支持向量机在回归问题上的应用,请参考:TODO 支持向量机分类广泛应用于图像识别.文本分类.生物信息学(例如基因分类).手写数字识别 ...

  9. Typecho 反向代理 http 访问强制启用生成 https 链接

    问题描述 微酷是使用Nginx反向代理内网的Typecho站点,为了效率内网访问不需要使用https,这样Typecho接收到的请求是http协议的,于是网站内部资源链接被修改成了http. 解决方案 ...

  10. osgEarth使用笔记3——加载倾斜摄影数据

    目录 1. 概述 2. 详论 2.1. 位置 2.2. 着色 2.3. 其他 3. 结果 4. 参考 1. 概述 我在<OSG加载倾斜摄影数据>这篇博文中论述了如何通过OSG生成一个整体的 ...