net包
所需的网络编程都在net
包下
大部分使用者只需要Dial
Listen
Accpet
函数提供的基本接口;以及相关的Conn
Listener
crypto/tls
包提供了相同的接口和类似的Dial
和 Listen
函数.
创建客户端
语法:
func Dial(network ,address string) (Conn,err)
地址格式:
1 2 3 4
| Dial("tcp", "12.34.56.78:80") Dial("tcp", "google.com:http") Dial("tcp", "[2001:db8::1]:http") Dial("tcp", "[fe80::1%lo0]:80")
|
对IP网络,network必须是”ip”、”ip4”、”ip6”后跟冒号和协议号或者协议名,地址必须是IP地址字面值。
1 2
| Dial("ip4:1", "127.0.0.1") Dial("ip6:ospf", "::1")
|
demo
1 2 3 4 5 6 7 8 9
|
conn, err := net.Dial("tcp", "127.0.0.1:10808") if err != nil { fmt.Println("客户端连接失败", err) return } fmt.Println("连接成功:", conn) fmt.Println("exit...")
|
通过客户端终端向服务器发送数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| reader := bufio.NewReader(os.Stdin)
str, err := reader.ReadString('\n') if err != nil { fmt.Println("读取用户输入的信息失败:", err) return }
n, err := conn.Write([]byte(str)) if err != nil { fmt.Println("向服务端发送数据失败:", err) } fmt.Printf("向服务端发送了%d个字节的数据\n", n)
|
创建服务器端
Listener是一个用于面向流的网络协议的公用的网络监听器接口.多个线程可能会同时调用一个listener的方法.
Listener接口例子:
1 2 3 4 5
| type Listener interface{ Addr() Addr Accept() (c Conn, err error) Close() error }
|
demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| fmt.Println("启动服务器端tcp") listen, err := net.Listen("tcp", ":8888") if err != nil { fmt.Println("监听失败:", err) return } fmt.Println("监听成功:", listen)
for { conn, err := listen.Accept() if err != nil { fmt.Println("监听失败:",err) continue } fmt.Println("conn:", conn) }
|
接收来自客户端发送的数据
需要再上面代码的for中添加一个go协程
go poress()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| func poress(conn net.Conn) { defer conn.Close() for { buf := make([]byte, 1024)
n, err := conn.Read(buf) if err != nil { return } fmt.Println("读取到来自客户端的数据:", string(buf[0:n])) } }
|
创建客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| import ( "encoding/json" "fmt" "net" )
func tcpClient() { conn, err := net.Dial("tcp", "127.0.0.1:2023") if err != nil { fmt.Println("拨号失败 :", err) return } defer conn.Close() for { mes := struct { UserName string Mes string }{ UserName: "用户1", } fmt.Println("请输入要发送的内容:") fmt.Scanf("%s\n", &mes.Mes) if mes.Mes == "" { fmt.Println("字符串为空") continue } if mes.Mes == "exit" { fmt.Println("退出程序") return } err = json.NewEncoder(conn).Encode(&mes) if err != nil { fmt.Println("发送失败") return } } }
|
创建服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| import ( "encoding/json" "fmt" "io" "net" )
func tcpServer() { listen, err := net.Listen("tcp", ":2023") if err != nil { fmt.Println("监听失败:", err) return } defer listen.Close() for { fmt.Println("主进程等待客户端连接...") conn, err := listen.Accept() if err != nil { fmt.Println("接听失败", err) continue } go func(conn net.Conn) { fmt.Println("一个客户端协程已开启") defer conn.Close() for {
mes := struct { UserName string Mes string }{} err := json.NewDecoder(conn).Decode(&mes) if err == io.EOF { fmt.Println("客户端退出") return } if err != nil { fmt.Println("读取失败", err) return } fmt.Printf("%v说:%v\n", mes.UserName, mes.Mes) } }(conn) } }
|