本篇文章主要介绍 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. JS对后端响应的long类型数据处理精度丢失问题

    1.数据库的数据 2.前端拿到的数据 前端帮我们进行四舍五入了,这并不是我想要的 3.解决办法 把后端响应的数据long类型转成string类型,可以使用Stream流的方式或者for循环的方式,对响 ...

  2. 【UniApp】-uni-app-CompositionAPI传递数据

    前言 好,经过上个章节的介绍完毕之后,了解了一下 uni-app-传递数据 那么了解完了uni-app-传递数据之后,这篇文章来给大家介绍一下 uni-app-CompositionAPI传递数据 首 ...

  3. django自带的cache缓存框架使用

    https://docs.djangoproject.com/zh-hans/4.2/topics/cache/#top 主要步骤官网也写得很清楚了,包含怎么区使用. 这里就展示一些配置django- ...

  4. 华企盾DSC导致wps个人模式无策略组新建的文件仍然加密

    解决方法:右键wps安装目录手动解密即可(原因:wps模板被加密导致)

  5. Collection和Map的区别

    Collection接口,包含list和set子接口Collection和Map接口之间的主要区别在于:Collection中存储了一组对象,而Map存储关键字/值对.在Map对象中,每一个关键字最多 ...

  6. MinIO客户端之ls

    MinIO提供了一个命令行程序mc用于协助用户完成日常的维护.管理类工作. 官方资料 mc ls 列出本地硬盘上的文件,命令如下: ./mc ls 控制台的输出,如下: [2023-12-14 23: ...

  7. CVE-2016-5734 复现

    CVE-2016-5734 漏洞简介 phpMyAdmin 4.0.x-4.6.2 远程代码执行漏洞(CVE-2016-5734) phpMyAdmin是一套开源的.基于Web的MySQL数据库管理工 ...

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

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

  9. 使用Bot Framework建立你的第一个聊天机器人

    今天微软给我推送了一个邮件,大概是微软近期开发了很多人工智能相关的API,无意中看到了Bot Framework,就点进去看了看似乎还蛮有意思的.于是准备搭建一个环境试试. 第一步需要下载Bot Ap ...

  10. webrtc实时视频语音实现

    webrtc介绍 WebRTC实现了基于网页的视频会议,标准是WHATWG 协议,目的是通过浏览器提供简单的javascript就可以达到实时通讯(Real-Time Communications ( ...