net.Dial()

当我们想要使用协议建立连接时,只需要调用 net.Dial() 函数就可以了,它接受两个参数,第一个参数是协议名,第二个参数是地址,返回值是一个连接对象 net.conn 和一个错误对象 err

1
conn, err := net.Dial("tcp", "192.168.10.10:80")

Dial() 函数目前支持以下网络协议:

  • tcp
  • tcp4(仅限IPv4)
  • tcp6(仅限IPv6)
  • udp
  • udp4(仅限IPv4)
  • udp6(仅限IPv6)
  • ip
  • ip4(仅限IPv4)
  • ip6(仅限IPv6)
  • unix
  • unixgram
  • unixpacket

在成功建立连接后,就可以进行数据的接收和发送,使用 conn.Write() 发送数据,使用 conn.Read() 接收数据,这两个函数都接受一个字节切片作为参数,返回值是发送或接收的字节数和一个错误对象

conn.Write()

1
_, err = conn.Write([]byte("HEAD / HTTP/1.0\r\n\r\n"))

conn.Read()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
func readFully(conn net.Conn) ([]byte, error) {

// 读取所有响应数据后主动关闭连接
defer conn.Close()

//创建字节缓冲区
result := bytes.NewBuffer(nil)

//存储每次从连接中读取的数据
var buf [512]byte
for {
n, err := conn.Read(buf[0:])
result.Write(buf[0:n])
if err != nil {

//判断是否到达数据流末尾
if err == io.EOF {
break
}
return nil, err
}
}
return result.Bytes(), nil
}

超时处理

连接超时

1
conn, err := net.DialTimeout("tcp", “192.168.1.1:80”, 3*time.Second)

DialTimeout()Dial() 函数一样,只是多设置了超时字段而已,而 Dial() 函数默认会使用操作系统提供的机制来处理连接超时

请求和响应超时

Conn 提供三个方法来设置请求和响应超时时间

  • SetDeadline() :设置读写超时时间
  • SetReadDeadline() :设置读超时时间
  • SetWriteDeadline() :设置写超时时间
1
err = conn.SetDeadline(time.Now().Add(100 * time.Second))

工具函数

net.ParseIP

net.ParseIP() 函数可以验证IP地址的有效性

net.IPv4Mask

net.IPv4Mask() 函数可以创建一个IPV4掩码

net.ResolveTCPAddr

1
structListenAddr, err := net.ResolveTCPAddr("tcp", "192.168.1.1:80")

net.ResolveTCPAddr 可以将一个TCP地址解析为一个TCP地址结构体,该函数会返回一个 net.TCPAddr 类型的地址结构体,包括解析后的IP地址和端口信息

net.Dialer

net.Dialer 是一个结构体,它封装了有关网络连接的更多选项,如超时时间、本地地址、代理设置等,允许用户进行更精细的控制

创建 net.Dialer 结构体后,可以使用它的 Dial 方法创建连接

1
2
3
4
5
6
dialer := &net.Dialer{Timeout: 5 * time.Second}
conn, err := dialer.Dial("tcp", "example.com:80")
if err != nil {
// 处理连接错误
}
// 使用 conn 进行数据的读写