Go语言基础之net/http
<h1 class="post-title"> </h1><div class="post-content">
<p>Go语言内置的<code>net/http</code>包十分的优秀,提供了HTTP客户端和服务端的实现。</p>
<h2 id="autoid-0-0-0">net/http介绍</h2>
<p>Go语言内置的<code>net/http</code>包提供了HTTP客户端和服务端的实现。</p>
<h3 id="autoid-0-1-0">HTTP协议</h3>
<p>超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。</p>
<h2 id="autoid-0-1-1">HTTP客户端</h2>
<h3 id="autoid-0-2-0">基本的HTTP/HTTPS请求</h3>
<p>Get、Head、Post和PostForm函数发出HTTP/HTTPS请求。</p>
<div class="cnblogs_code">
<pre>resp, err := http.Get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://example.com/</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
...
resp, err :</span>= http.Post(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://example.com/upload</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">image/jpeg</span><span style="color: rgba(128, 0, 0, 1)">"</span>, &<span style="color: rgba(0, 0, 0, 1)">buf)
...
resp, err :</span>= http.PostForm(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://example.com/form</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
url.Values{</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">key</span><span style="color: rgba(128, 0, 0, 1)">"</span>: {<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Value</span><span style="color: rgba(128, 0, 0, 1)">"</span>}, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">id</span><span style="color: rgba(128, 0, 0, 1)">"</span>: {<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">123</span><span style="color: rgba(128, 0, 0, 1)">"</span>}})</pre>
</div>
<p> </p>
<p>程序在使用完response后必须关闭回复的主体。</p>
<div class="cnblogs_code">
<pre>resp, err := http.Get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://example.com/</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> handle error</span>
<span style="color: rgba(0, 0, 0, 1)">}
defer resp.Body.Close()
body, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> ioutil.ReadAll(resp.Body)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ...</span></pre>
</div>
<p> </p>
<h3 id="autoid-0-2-1">GET请求示例</h3>
<p>使用<code>net/http</code>包编写一个简单的发送HTTP请求的Client端,代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">package main
import (
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">fmt</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">io/ioutil</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">net/http</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
func main() {
resp, err :</span>= http.Get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">https://www.liwenzhou.com/</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">get failed, err:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, err)
return
}
defer resp.Body.Close()
body, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> ioutil.ReadAll(resp.Body)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">read from resp.Body failed,err:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, err)
return
}
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Print(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">(body))
}</span></pre>
</div>
<p> </p>
<p>将上面的代码保存之后编译成可执行文件,执行之后就能在终端打印<code>liwenzhou.com</code>网站首页的内容了,我们的浏览器其实就是一个发送和接收HTTP协议数据的客户端,我们平时通过浏览器访问网页其实就是从网站的服务器接收HTTP数据,然后浏览器会按照HTML、CSS等规则将网页渲染展示出来。</p>
<h3 id="autoid-0-2-2">带参数的GET请求示例</h3>
<p>关于GET请求的参数需要使用Go语言内置的<code>net/url</code>这个标准库来处理。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">func main() {
apiUrl :</span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://127.0.0.1:9090/get</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> URL param</span>
data :=<span style="color: rgba(0, 0, 0, 1)"> url.Values{}
data.Set(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">小王子</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
data.Set(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">age</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">18</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
u, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> url.ParseRequestURI(apiUrl)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Printf(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">parse url requestUrl failed,err:%v\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, err)
}
u.RawQuery </span>= data.Encode() <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> URL encode</span>
<span style="color: rgba(0, 0, 255, 1)">fmt</span><span style="color: rgba(0, 0, 0, 1)">.Println(u.String())
resp, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> http.Get(u.String())
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">post failed, err:%v\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, err)
return
}
defer resp.Body.Close()
b, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> ioutil.ReadAll(resp.Body)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">get resp failed,err:%v\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, err)
return
}
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">(b))
}</span></pre>
</div>
<p> </p>
<p>对应的Server端HandlerFunc如下:</p>
<div class="cnblogs_code">
<pre>func getHandler(<span style="color: rgba(0, 0, 255, 1)">w</span> http.ResponseWriter, r *<span style="color: rgba(0, 0, 0, 1)">http.Request) {
defer r.Body.Close()
data :</span>=<span style="color: rgba(0, 0, 0, 1)"> r.URL.Query()
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(data.Get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">))
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(data.Get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">age</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">))
answer :</span>= `{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">status</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ok</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">}`
</span><span style="color: rgba(0, 0, 255, 1)">w</span>.Write([]<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">(answer))
}</span></pre>
</div>
<p> </p>
<h3 id="autoid-0-2-3">Post请求示例</h3>
<p>上面演示了使用<code>net/http</code>包发送<code>GET</code>请求的示例,发送<code>POST</code>请求的示例代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">package main
import (
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">fmt</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">io/ioutil</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">net/http</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">strings</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> net/http post demo</span>
<span style="color: rgba(0, 0, 0, 1)">
func main() {
url :</span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://127.0.0.1:9090/post</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 表单数据
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">contentType := "application/x-www-form-urlencoded"
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">data := "name=小王子&age=18"
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> json</span>
contentType := <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">application/json</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
data :</span>= `{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">小王子</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">age</span><span style="color: rgba(128, 0, 0, 1)">"</span>:<span style="color: rgba(128, 0, 128, 1)">18</span><span style="color: rgba(0, 0, 0, 1)">}`
resp, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> http.Post(url, contentType, strings.NewReader(data))
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">post failed, err:%v\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, err)
return
}
defer resp.Body.Close()
b, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> ioutil.ReadAll(resp.Body)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">get resp failed,err:%v\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, err)
return
}
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">(b))
}</span></pre>
</div>
<p> </p>
<p>对应的Server端HandlerFunc如下:</p>
<div class="cnblogs_code">
<pre>func postHandler(<span style="color: rgba(0, 0, 255, 1)">w</span> http.ResponseWriter, r *<span style="color: rgba(0, 0, 0, 1)">http.Request) {
defer r.Body.Close()
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 1. 请求类型是application/x-www-form-urlencoded时解析form数据</span>
<span style="color: rgba(0, 0, 0, 1)"> r.ParseForm()
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(r.PostForm) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 打印form数据</span>
<span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(r.PostForm.Get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>), r.PostForm.Get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">age</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">))
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 2. 请求类型是application/json时从r.Body读取数据</span>
b, err :=<span style="color: rgba(0, 0, 0, 1)"> ioutil.ReadAll(r.Body)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">read request.Body failed, err:%v\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, err)
return
}
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Println(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">(b))
answer :</span>= `{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">status</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ok</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">}`
</span><span style="color: rgba(0, 0, 255, 1)">w</span>.Write([]<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">(answer))
}</span></pre>
</div>
<p> </p>
<h3 id="autoid-0-2-4">自定义Client</h3>
<p>要管理HTTP客户端的头域、重定向策略和其他设置,创建一个Client:</p>
<div class="cnblogs_code">
<pre>client := &<span style="color: rgba(0, 0, 0, 1)">http.Client{
CheckRedirect: redirectPolicyFunc,
}
resp, err :</span>= client.Get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://example.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ...</span>
req, err := http.NewRequest(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">GET</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://example.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, nil)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ...</span>
req.Header.Add(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">If-None-Match</span><span style="color: rgba(128, 0, 0, 1)">"</span>, `W/<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">wyzzy</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`)
resp, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> client.Do(req)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ...</span></pre>
</div>
<p> </p>
<h3 id="autoid-0-2-5">自定义Transport</h3>
<p>要管理代理、TLS配置、keep-alive、压缩和其他设置,创建一个Transport:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">tr</span> := &<span style="color: rgba(0, 0, 0, 1)">http.Transport{
TLSClientConfig: </span>&<span style="color: rgba(0, 0, 0, 1)">tls.Config{RootCAs: pool},
DisableCompression: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
}
client :</span>= &http.Client{Transport: <span style="color: rgba(0, 0, 255, 1)">tr</span><span style="color: rgba(0, 0, 0, 1)">}
resp, err :</span>= client.Get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">https://example.com</span><span style="color: rgba(128, 0, 0, 1)">"</span>)</pre>
</div>
<p> </p>
<p>Client和Transport类型都可以安全的被多个goroutine同时使用。出于效率考虑,应该一次建立、尽量重用。</p>
<h2 id="autoid-0-2-6">服务端</h2>
<h3 id="autoid-0-3-0">默认的Server</h3>
<p>ListenAndServe使用指定的监听地址和处理器启动一个HTTP服务端。处理器参数通常是nil,这表示采用包变量DefaultServeMux作为处理器。</p>
<p>Handle和HandleFunc函数可以向DefaultServeMux添加处理器。</p>
<div class="cnblogs_code">
<pre>http.Handle(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/foo</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, fooHandler)
http.HandleFunc(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/bar</span><span style="color: rgba(128, 0, 0, 1)">"</span>, func(<span style="color: rgba(0, 0, 255, 1)">w</span> http.ResponseWriter, r *<span style="color: rgba(0, 0, 0, 1)">http.Request) {
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Fprintf(<span style="color: rgba(0, 0, 255, 1)">w</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Hello, %q</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, html.EscapeString(r.URL.Path))
})
log.Fatal(http.ListenAndServe(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">:8080</span><span style="color: rgba(128, 0, 0, 1)">"</span>, nil))</pre>
</div>
<p> </p>
<h3 id="autoid-0-3-1">默认的Server示例</h3>
<p>使用Go语言中的<code>net/http</code>包来编写一个简单的接收HTTP请求的Server端示例,<code>net/http</code>包是对net包的进一步封装,专门用来处理HTTP协议的数据。具体的代码如下:</p>
<pre class="line-numbers language-go"><code class=" language-go"><span class="token comment">// http server</span></code></pre>
<div class="cnblogs_code">
<pre>func sayHello(<span style="color: rgba(0, 0, 255, 1)">w</span> http.ResponseWriter, r *<span style="color: rgba(0, 0, 0, 1)">http.Request) {
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Fprintln(<span style="color: rgba(0, 0, 255, 1)">w</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Hello 沙河!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
}
func main() {
http.HandleFunc(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, sayHello)
err :</span>= http.ListenAndServe(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">:9090</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, nil)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Printf(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http server failed, err:%v\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, err)
return
}
}</span></pre>
</div>
<p> </p>
<p>将上面的代码编译之后执行,打开你电脑上的浏览器在地址栏输入<code>127.0.0.1:9090</code>回车,此时就能够看到如下页面了。<img src="https://www.liwenzhou.com/images/Go/socket/hello.png"></p>
<h3 id="autoid-0-3-2">自定义Server</h3>
<p>要管理服务端的行为,可以创建一个自定义的Server:</p>
<div class="cnblogs_code">
<pre>s := &<span style="color: rgba(0, 0, 0, 1)">http.Server{
Addr: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">:8080</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
Handler: myHandler,
ReadTimeout: </span><span style="color: rgba(128, 0, 128, 1)">10</span> * <span style="color: rgba(0, 0, 255, 1)">time</span><span style="color: rgba(0, 0, 0, 1)">.Second,
WriteTimeout: </span><span style="color: rgba(128, 0, 128, 1)">10</span> * <span style="color: rgba(0, 0, 255, 1)">time</span><span style="color: rgba(0, 0, 0, 1)">.Second,
MaxHeaderBytes: </span><span style="color: rgba(128, 0, 128, 1)">1</span> << <span style="color: rgba(128, 0, 128, 1)">20</span><span style="color: rgba(0, 0, 0, 1)">,
}
log.Fatal(s.ListenAndServe())</span></pre>
</div>
<p> </p>
</div><br><br>
来源:https://www.cnblogs.com/wukai66/p/12031603.html
頁:
[1]