目录
一、net包的基本功能
1.1 IP地址处理
1.2 网络协议支持
1.3 连接管理
二、net包的主要功能模块
2.1 IP地址处理
2.2 TCP协议
2.3 UDP协议
2.4 Listener和Conn接口
三、高级功能
3.1 超时设置
3.2 KeepAlive控制
3.3 获取连接信息
四、实际应用场景
4.1 Web服务器
4.2 实时通信
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协议进行数据报送。