GoLang之网络
本文内容纲要:
-GoLang之网络
-HTTP协议
-HTTP客户端
-HTTP服务端
-RPC协议
-json处理
GoLang之网络
Go语言标准库里提供的net包,支持基于IP层、TCP/UDP层及更高层面(如HTTP、FTP、SMTP)的网络操作,其中用于IP层的称为RawSocket。
net包的Dial()函数用于创建网络连接,函数原型如下:
funcDial(net,addrstring)(Conn,error)
其中net参数是网络协议的名字,addr参数是IP地址或域名;如果连接成功,返回连接对象,否则返回error。
目前,Dial()函数支持如下几种网络协议:"tcp"、"udp"、"ip"、"ip6"等,例如:
conn,err:=net.Dial("tcp","192.168.0.10:2100")//TCP连接
conn,err:=net.Dial("udp","192.168.0.12:975")//UDP连接
conn,err:=net.Dial("ip4:icmp","www.baidu.com")//ICMP连接
在成功连接连接后,可以使用conn的Write()和Read()方法读写数据。
实际上,Dial()函数是对DialTCP()、DialUDP()、DialIP()、DialUnix()函数的封装:
funcDialTCP(netstring,laddr,raddr*TCPAddr)(c*TCPConn,errerror)
funcDialUDP(netstring,laddr,raddr*UDPAddr)(c*UDPConn,errerror)
funcDialIP(netProtostring,laddr,raddr*IPAddr)(c*IPConn,errerror)
funcDialUnix(netstring,laddr,raddr*UnixAddr)(c*UnixConn,errerror)
下面是一个TCP示例程序:
funccheckError(errerror){
iferr!=nil{
fmt.Fprintf(os.Stderr,"Fatalerror:%s",err.Error())
os.Exit(1)
}
}
funcreadFully(connnet.Conn)([]byte,error){
deferconn.Close()
result:=bytes.NewBuffer(nil)
varbuf[512]byte
for{
n,err:=conn.Read(buf[0:])
result.Write(buf[0:n])
iferr!=nil{
iferr==io.EOF{
break
}
returnnil,err
}
}
returnresult.Bytes(),nil
}
funcmain(){
addr:="127.0.0.1:80"
conn,err:=net.Dial("tcp",addr)
checkError(err)
_,err=conn.Write([]byte("GET/api/v3/getHTTP/1.1\r\n\r\n"))
checkError(err)
result,err:=readFully(conn)
checkError(err)
fmt.Println(string(result))
os.Exit(0)
}
HTTP协议
Go语言标准库内建提供了net/http包,涵盖了HTTP客户端和服务端的具体实现。
HTTP客户端
net/http包的Client类型提供了如下几个方法:
func(c*Client)Get(urlstring)(r*Response,errerror)
func(c*Client)Post(urlstring,bodyTypestring,bodyio.Reader)(r*Response,errerror)
func(c*Client)PostForm(urlstring,dataurl.Values)(r*Response,errerror)
func(c*Client)Head(urlstring)(r*Response,errerror)
func(c*Client)Do(req*Request)(r*Response,errerror)
以GET方法为例:
resp,err:=http.Get("http://cre.mix.sina.com.cn/api/v3/get")
iferr!=nil{
fmt.Println("getfailed",err)
return
}
deferresp.Body.Close()
io.Copy(os.Stdout,resp.Body)
上面这段代码请求一个网站首页,并将其内容打印到标准输出流中。
如果希望对请求做更多的控制,可以使用DO()方法:
req,err:=http.NewRequest("GET","http://cre.mix.sina.com.cn/api/v3/get",nil)
req.Header.Add("User-Agent","GoGO")
client:=&http.Client{}
resp,err:=client.Do(req)
HTTP服务端
使用net/http包提供的下面两个方法
funcListenAndServe(addrstring,handlerHandler)error
funcListenAndServeTLS(addrstring,certFilestring,keyFilestring,handlerHandler)error
ListenAndServe()函数有2个参数,第一个参数addr即监听地址,第二个参数表示服务端处理程序,通常为空,使用默认的http.DefaultServeMux进行处理。
服务端的业务逻辑使用http.Handle()或http.HandleFunc(),会默认注入http.DefaultServeMux中,如:
http.HandleFunc("/foo",func(whttp.ResponseWriter,r*http.Request){
fmt.Fprintf(w,"Hello,%q",html.EscapeString(r.URL.Path))
})
http.ListenAndServe(":8001",nil)
RPC协议
在Go中,标准库提供的net/rpc包实现了PRC协议需要的相关细节,开发者可以很方便地使用该包编写RPC的服务端和客户端程序。
json处理
在Web开发领域中,JSON被广泛用于web服务端程序和客户端之间的数据通信。
Go语言内建对JSON的支持,使用encoding/json标准库,开发者可以轻松使用Go程序生成和解析JSON格式的数据。
funcMarshal(vinterface{})([]byte,error)
funcUnmarshal(vdata[]byte,vinterface{})error
JSON编码的一个例子:
typeBookstruct{
Titlestring
Authors[]string
Publisherstring
IsPublishedbool
Pricefloat32
}
funcmain(){
gobook:=Book{
"Goprogramming",
[]string{"XuShiwei","HughLv","Johnson"},
"isturing.com.cn",
true,
9.99,
}
//encode
b,err:=json.Marshal(gobook)//变量b是一个[]byte类型
iferr==nil{
fmt.Println(b)
}
//decode
varbookBook
json.Unmarshal(b,&book)
fmt.Println(book)
}
当我们调用json.Marshal(gobook)函数时,会递归遍历gobook对象,如果发现gobook这个数据结构实现了json.Marshaler接口且包含有效的值,Marshal()就会调用其MarshalJSON()方法将该数据结构生成JSON格式的文本。
Go语言的大多数类型都可以转化为有效的JSON文本,但channel、complex和函数这几种类型除外;而对于指针,会转化为指针所指向的值,如果指针指向的是零值,那么null将作为转化后输出的结果。具体的转化规则如下:
- 布尔值转化为JSON的bool类型;
- 浮点数和整型转化为JSON的number类型;
- 字符串将以UTF-8编码转化为Unicode字符集的字符串;
- 数组和切片转化为JSON的array类型,但[]byte类型的值会被转化为Base64编码后的字符串,slice类型的零值会被转化为null;
- 结构体转化为JSON的object类型,并且只有结构体中以大写字母开头的可被导出的字段才会被转化输出;
- 转化一个map类型的数据结构时,该数据的类型必须是map[string]T。
本文内容总结:GoLang之网络,HTTP协议,HTTP客户端,HTTP服务端,RPC协议,json处理,
原文链接:https://www.cnblogs.com/chenny7/p/4499164.html