go的网络应用方面程序的编写都在net包里面, 比如net/http, net/rpc, net/mail, net/smtp 等, 今天我们主要来讲解如何使用net/socket 来编写一个socket 客户端和服务端
使用net包来检查 ip 地址是否是合法的ip 地址
我们可以使用net.ParseIP() 方法来检查, 如果该方法返回了nil 则说明ip 地址是错误的,比如 192.168.1.256 这种就不是合法的地址
使用net/socket 编写socket server(TCP)
一般的编写socket 服务端都分为几个步骤 1. bind 2. listen 3. accept 4. recv/send data 5. close
bind 步骤使用 net.ResolveTCPAddr(), 来实现这个是TCP类型的socket, 这个方法接收两个参数1, ip 协议类型, 一般就是tcp4 和 tcp6, 该方法返回两个结果, *TCPAddr, error
listen 步骤使用net.ListenTCP(),来实现,这个方法接收两个参数, 第一个是协议类型,我们这里是tcp的socket ,因此就写tcp, 第二个参数是 *TCPAddr 也就是 ResolveTCPAddr()这个方法返回的
服务端代码
package growth
import (
"fmt"
"net"
"sync"
)
// go 学习第十八天 学习go socket
var waitGroup sync.WaitGroup
func Day18Socket() {
// net 包的ParseIP 可以检查ip 地址格式是否正确
checkValidIp := "192.168.1.255"
result := net.ParseIP(checkValidIp)
if result == nil {
fmt.Println("ip 地址错误")
}else {
fmt.Println("ip 地址是", result)
}
addr := "127.0.0.1:8888"
Server(addr)
}
func Server(listen string) {
bind, e5 := net.ResolveTCPAddr("tcp4", listen)
if e5 != nil {
fmt.Println("server ip 地址有误")
return
}
listener, e6 := net.ListenTCP("tcp", bind)
if e6 != nil {
fmt.Println("绑定失败,", e6)
}
for {
count := 1
conn, e7 := listener.Accept()
fmt.Println("accept", conn.RemoteAddr())
if e7 != nil {
continue
}
go handler(conn)
count += 1
waitGroup.Add(count)
fmt.Println("wait ....")
}
}
func handler(connect net.Conn) {
fmt.Println("处理请求,", connect.RemoteAddr())
defer waitGroup.Done()
defer connect.Close()
var recv []byte
data, err := connect.Read(recv)
if err != nil {
fmt.Println("服务端读取数据错误")
return
}
fmt.Println("接收到客户端数据", string(data))
connect.Write([]byte("hello client"))
}
使用net/socket 编写socket client(TCP)
client 使用 net.DialTCP()来建立个服务端的连接
客户端代码
package growth
import (
"net"
"fmt"
"io/ioutil"
)
// go 学习第十八天 学习go socket
func Client() {
// go 里面通过ResolveTCPAddr获取连接地址
// net参数是"tcp4"、"tcp6"、"tcp"中的任意一个 , addr表示域名或者IP地址
addr := "127.0.0.1:8888"
server, err := net.ResolveTCPAddr("tcp4", addr)
if err != nil {
fmt.Println("ip 有误, ", err)
return
}
conn, e2 := net.DialTCP("tcp", nil, server)
if e2 != nil {
fmt.Println("连接失败,", e2)
return
}else {
// 往服务端发送数据
_, e3 := conn.Write([]byte("hello world!"))
if e3 != nil {
fmt.Println("发送失败", e3)
return
}
resp, e4 := ioutil.ReadAll(conn)
if e4 != nil {
fmt.Println("读取数据错误", e4)
return
}else {
fmt.Println("收到响应", resp)
}
fmt.Println("end -=-=-=-=-=-=->")
}
}