目录
[1.1 IP地址处理](#1.1 IP地址处理)
[1.2 网络协议支持](#1.2 网络协议支持)
[1.3 连接管理](#1.3 连接管理)
[2.1 IP地址处理](#2.1 IP地址处理)
[2.2 TCP协议](#2.2 TCP协议)
[2.3 UDP协议](#2.3 UDP协议)
[2.4 Listener和Conn接口](#2.4 Listener和Conn接口)
[3.1 超时设置](#3.1 超时设置)
[3.2 KeepAlive控制](#3.2 KeepAlive控制)
[3.3 获取连接信息](#3.3 获取连接信息)
[4.1 Web服务器](#4.1 Web服务器)
[4.2 实时通信](#4.2 实时通信)
[4.3 数据报送](#4.3 数据报送)
Go语言的net
包是处理网络通信的核心库,它提供了底层的网络接口,包括TCP、UDP、IP等协议的支持。net
包的功能强大,使用灵活。
一、net包的基本功能
net
包主要用来处理网络通信,提供了包括IP地址处理、协议侦听、数据报送等功能。
1.1 IP地址处理
net
包中提供了IP
地址的解析、比较、检查等功能。IPAddress
接口定义了String()
、Netmask()
等方法,可以用来获取IP地址的字符串表示以及子网掩码。
1.2 网络协议支持
net
包支持多种网络协议,包括TCP、UDP、IP、Unix域套接字等。通过不同的协议,可以创建监听器(Listener)和连接(Conn)。例如,使用net.Listen("tcp", "localhost:8080")
可以创建一个TCP协议的监听器。
1.3 连接管理
net
包提供了Conn
接口,用来表示一个网络连接。通过Conn
接口可以进行数据的读写操作,同时也可以获取连接的本地和远程地址。
二、net包的主要功能模块
2.1 IP地址处理
net
包中IPAddress
接口提供了对IP地址的处理方法。例如,可以使用net.ParseIP()
函数解析一个IP地址字符串。
示例代码:
ip := net.ParseIP("192.168.1.1")
if ip != nil {
fmt.Printf("IP address: %s\n", ip.String())
} else {
fmt.Println("Invalid IP address")
}
2.2 TCP协议
TCP协议是面向连接的可靠协议,适合需要保证数据完整性的应用场景。net
包通过net/tcp
包提供了对TCP协议的支持。
TCP服务器示例:
listener, err := net.Listen("tcp", "localhost:8080")
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Printf("Failed to accept connection: %v", err)
continue
}
go handleConnection(conn)
}
TCP客户端示例:
conn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
log.Fatalf("Failed to dial: %v", err)
}
defer conn.Close()
_, err = conn.Write([]byte("Hello, server!"))
if err != nil {
log.Printf("Failed to write: %v", err)
}
2.3 UDP协议
UDP协议是无连接的不可靠协议,适合实时性要求高但对数据完整性不敏感的场景。net
包通过net/udp
包提供了对UDP协议的支持。
UDP服务器示例:
conn, err := net.ListenPacket("udp", ":8080")
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
defer conn.Close()
buf := make([]byte, 1024)
for {
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Printf("Failed to read: %v", err)
continue
}
go handlePacket(buf[:n], addr)
}
UDP客户端示例:
conn, err := net.Dial("udp", "localhost:8080")
if err != nil {
log.Fatalf("Failed to dial: %v", err)
}
defer conn.Close()
_, err = conn.Write([]byte("Hello, server!"))
if err != nil {
log.Printf("Failed to write: %v", err)
}
2.4 Listener和Conn接口
net
包中Listener
接口和Conn
接口是网络通信的核心接口。Listener
接口用于监听传入的连接,而Conn
接口则表示一个已建立的网络连接。
Listener接口方法:
Accept()
: 接受一个新的连接。Close()
: 关闭监听器。Addr()
: 获取监听器的地址。
Conn接口方法:
Read(b []byte)
: 从连接中读取数据。Write(b []byte)
: 向连接中写入数据。Close()
: 关闭连接。LocalAddr()
: 获取本地地址。RemoteAddr()
: 获取远程地址.
三、高级功能
3.1 超时设置
在网络通信中,超时设置用于防止因网络问题导致的长时间无响应。Go语言的net
包提供了多种方式设置超时。
示例代码:
// 设置连接超时
conn, err := net.DialTimeout("tcp", "localhost:8080", 5*time.Second)
if err != nil {
log.Printf("Failed to dial: %v", err)
}
defer conn.Close()
// 设置读写超时
conn.SetDeadline(time.Now().Add(10 * time.Second))
3.2 KeepAlive控制
在长时间没有数据传输的连接中,可能会因为网络设备的策略导致连接被关闭。net
包提供了SetKeepAlive
方法用于配置KeepAlive选项。
示例代码:
// 创建TCP连接
conn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
log.Printf("Failed to dial: %v", err)
}
defer conn.Close()
// 配置KeepAlive
conn.SetKeepAlive(true)
3.3 获取连接信息
net
包还提供了一些方法来获取连接的详细信息。例如,可以通过conn.LocalAddr()
和conn.RemoteAddr()
方法获取本地和远程的地址信息。
示例代码:
localAddr := conn.LocalAddr()
remoteAddr := conn.RemoteAddr()
fmt.Printf("Local address: %v\n", localAddr)
fmt.Printf("Remote address: %v\n", remoteAddr)
四、实际应用场景
4.1 Web服务器
net
包是构建Web服务器的基础。在使用net/http
包之前,net
包已经提供了底层的网络通信功能。
示例代码:
package main
import (
"fmt"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", helloHandler)
fmt.Println("Starting server on :8080")
http.ListenAndServe(":8080", nil)
}
4.2 实时通信
在需要实时通信的场景中,可以使用net
包搭配WebSocket协议来实现客户端和服务器之间的双向实时通信。
这里举例一个单向的:
服务端:接收客户端传来的消息
package main
import (
"fmt"
"net"
)
func process(conn net.Conn) {
defer conn.Close()
for {
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
return
}
fmt.Println(string(buf[:n]))
}
}
func main() {
fmt.Println("服务端启动")
listen, err := net.Listen("tcp", "127.0.0.1:8080")
if err != nil {
fmt.Println("监听失败")
return
}
for {
conn, err2 := listen.Accept()
if err2 != nil {
fmt.Println("客户端等待失败", err2)
} else {
fmt.Println("连接成功", conn, conn.RemoteAddr())
}
go process(conn)
}
}
客户端:向服务端发送消息
package main
import (
"bufio"
"fmt"
"net"
"os"
)
func main() {
fmt.Println("客户端启动")
conn, err1 := net.Dial("tcp", "127.0.0.1:8080")
if err1 != nil {
fmt.Println("客户端连接失败:", err1)
return
}
fmt.Println("连接成功.", conn)
reader := bufio.NewReader(os.Stdin)
for {
str, err2 := reader.ReadString('\n')
if err2 != nil {
fmt.Println("终端输入失败", err2)
}
if str == "exit\n" {
return
}
n, err3 := conn.Write([]byte(str))
if err3 != nil {
fmt.Println("连接失败", err3)
}
fmt.Printf("发送了%d个字节\n", n)
}
}
4.3 数据报送
对于需要快速传输数据且对可靠性要求不高的场景,可以使用UDP协议进行数据报送。