从0开始go语言-16|Go主题月

668 阅读4分钟

网 络 编 程

如何用Go语言网络编程,Go语言库中提供了net包,支持基于IP层,TCP/UDP层及更高的层面(HTTP,FTP)等网络协议。ip层被称为RawSocket。

Socket编程

传统的Socket编程时一般会一步步展开调用。如下:

  • 建立Socket:使用socket()函数
  • 绑定socket函数:使用bind()函数
  • 监听:使用listen()函数,或者链接使用connect()函数
  • 连接:使用accept()函数
  • 接收:使用receive()函数。或者发送:使用send()函数 Go语言中把上述所有的步骤进行了封装和抽象,只需要调用一个函数net.Dial()搞定!!!

Dial()函数

Dial()函数如下:

func Dial(net, addr string) (Conn, error)
  • net:网络协议的名字
  • addr:IP地址或域名,可以带端口号如需要访问8080端口ip:8080 连接成功返回连接对象,连接失败返回error信息。举例说明:

TCP连接:

conn, err := net.Dial("tcp", "192.168.0.1:9100")

UDP链接:

conn, err := net.Dial("udp", "192.168.0.1:339")

ICMP链接(协议名称)

conn, err := net.Dial("ip4:icmp", "www.juejin.cn")

ICMP链接(协议编号):

conn, err := net.Dial("ip4:1", "117.34.47.240")

成功建立连接后,可以进行数据的发送和接收。发送数据时,使用conn的Write()成员方法,接收数据时使用Read()方法。

HTTP 编程

HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最为广泛的一种网络协议,定义了客户端和服务端之间请求与响应的传输标准。

Go语言标准库内建提供了net/http包,涵盖了HTTP客户端和服务端的具体实现。使用net/http包,可以很方便地编写HTTP客户端或服务端的程序。

HTTP客户端

基本方法

net/http包的Client类型提供了如下的方法,可以用最简洁的方式实现HTTP请求:

func (c *Client) Get(url string) (r *Response, err error) 
func (c *Client) Post(url string, bodyType string, body io.Reader) (r *Response, err 
 error) 
func (c *Client) PostForm(url string, data url.Values) (r *Response, err error) 
func (c *Client) Head(url string) (r *Response, err error) 
func (c *Client) Do(req *Request) (resp *Response, err error)

http.Get()

java中利用工具类RestTemplate,请求目标url,返回json对象如下:

@Autowired
private RestTemplate restTemplate;
JSONObject jsonObject = restTemplate.getForObject(url, JSONObject.class);

Go语言中需要调用一个网站返回网站信息打印,如下:

resp, err := http.Get("https://juejin.cn/") 
if err != nil { 
 // 处理错误 ... 
 return
} 
defer resp.Body.close() 
io.Copy(os.Stdout, resp.Body)

http.Post()

java中post请求利用工具类RestTemplate,请求目标url,请求body内容为json,返回字符串为String格式如下:

@Autowired
private RestTemplate restTemplate;
String strsuiteAccessToken= restTemplate.postForObject(url, json, String.class);

Go语言中post方法需要传三个参数:请求目标url,资源类型(MIMEType),数据的比特流([]byte形式)。如下上传图片的post请求:

resp, err := http.Post("http://ks3.com/upload", "image/jpeg", &imageDataBuf) 
if err != nil { 
 // 处理错误
 return
} 
if resp.StatusCode != http.StatusOK { 
 // 处理错误
 return
} 
// ...

http.PostForm()

http.PostForm()方法实现了标准编码格式为application/x-www-form-urlencoded的表单提交,一般是前端HTML页面提交Form表单里面的内容提交到后台用Form表单提交。如下:

resp, err := http.PostForm("http://jeujin.com/post", url.Values{"title": 
 {"article title"}, "content": {"article body"}}) 
if err != nil { 
 // 处理错误
 return
} 
// ...

http.Head()

HTTP中的Head请求方式表明只请求目标URL的头部信息,同http.Get()方法一样,只需传入目标URL一个参数即可

resp, err := http.Head("http://juejin.com/")

(*http.Client).Do()

如果发起的HTTP请求需要更多的定制信息,我们希望设定一些自定义的Http Header字段,比如设定自定义的"User-Agent",而不是默认的 "Go http package",比如我需要在Head加一个加密字段用于验签。

req, err := http.NewRequest("GET", "http://example.com", nil) 
// ... 
req.Header.Add("User-Agent", "Gobook Custom User-Agent") 
req.Header.Add("sign", "13w9kjkjijdkw") 
// ... 
// ... 
client := &http.Client{ //... } 
resp, err := client.Do(req)

除了基本HTTP操作,Go语言标准库也暴露了比较底层的HTTP相关库,让开发者可以基于这些库灵活定制HTTP服务和使用HTTP服务。比如自定义http.Client,自定义http.Transport,和自定义 http.RoundTripper接口。

GO语言中的HTTP可以抽象的分为“业务层”和“传输层”,通常调用方式在业务层写的,他们只关注业务的本身逻辑,而无需关心非业务相关的技术如下细节:

  • HTTP 底层传输细节
  • HTTP 代理
  • gzip 压缩
  • 连接池及其管理
  • 认证(SSL或其他认证方式) HTTP Client 在底层抽象了http.RoundTripper 接口,而http.Transport实现了该接口,从而能够处理更多的细节,这一层可称为“传输层”,通过业务层封装目标url,目标资源,请求参数等,经过传输层去请求目标资源,然后响应请求。在客户端和服务端建立连接和断开连接,http协议还有很经典的“三次握手四次挥手”的约定。这是后话下回分解!!

备注

本文正在参与「掘金Golang主题学习月」, 点击查看活动详情