2018-07-20 11:50:06

goweb-038-常用包net+http

网络操作(计算机网络相关知识可以利用此包实践)

net

  • net包提供了可移植的网络I/O接口,包括TCP/IPUDP、域名解析和Unixsocket
  • 本包提供了对网络原语的访问,大部分使用者只需要DialListenAccept函数提供的基本接口;以及相关的ConnListener接口。

过程

  1. 服务端程序 Listen 监听某个端口,等待客户端程序的连接请求Accept
  2. 客户端程序 Dial 申请连接。
  3. 服务端程序 处理连接请求并建立网络连接 Conn
  4. 双方在Conn 进行读Read/写Write操作传递数据。

代码示例
server

package main
import (
    "net"
)
func main() {
    //监听端口
    listen, _ := net.Listen("tcp", `:88`)
    for {
        //等待连接连接并建立连接
        conn, _ := listen.Accept()
        //通过连接发送数据
        conn.Write([]byte(`hello 我是服务端`))
    }
}

client

package main
import (
    "fmt"
    "net"
)
func main() {
    //请求建立连接
    conn, _ := net.Dial("tcp", ":88")
    //数据容器
    buf := make([]byte, 1024)
    //读取数据到容器
    l, _ := conn.Read(buf)
    //打印输出
    fmt.Println(string(buf[:l]))
}

模拟http
浏览器访问 http://127.0.0.1:86/查看效果

alt

package main
import (
    "fmt"
    "net"
)
func main() {
    //监听端口
    listen, _ := net.Listen("tcp", `:86`)
    //等待连接连接并建立连接
    conn, _ := listen.Accept()
    //http半双工需要先读取里面的数据
    buf := make([]byte, 1024)
    l, _ := conn.Read(buf)
    fmt.Println(string(buf[:l]))
    //通过连接发送数据
    //http 协议格式
    conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Type: text/plain;charset=UTF-8\r\n\r\n数据开始:net模拟http"))
    conn.Close()
}

浏览器
alt
控制台
alt

http

官方文档
net的上层封装

  • http包提供了HTTP客户端和服务端的实现。

Get, Head, Post, and PostForm make HTTP (or HTTPS) requests:

//普通get请求
resp, err := http.Get("http://example.com/")
//上传文件
bodyBuf := &bytes.Buffer{}
bodyWriter := multipart.NewWriter(bodyBuf)
fileWriter, _ := bodyWriter.CreateFormFile("file", "main.go")
fh, _ := os.Open("main.go")
defer fh.Close()
io.Copy(fileWriter, fh)
ctype := bodyWriter.FormDataContentType()
bodyWriter.Close()
http.Post("http://127.0.0.1/up", ctype, bodyBuf)

//提交数据
resp, err := http.PostForm("http://example.com/form",
    url.Values{"key": {"Value"}, "id": {"123"}})

The client must close the response body when finished with it:

resp, err := http.Get("http://example.com/")
if err != nil {
    // handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
// ...

For control over HTTP client headers, redirect policy, and other settings, create a Client:

client := &http.Client{
}

resp, err := client.Get("http://example.com")
// ...

req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)

爬取页面

package main
import (
    "fmt"
    "io/ioutil"
    "net/http"
    "regexp"
)
func main() {
    //发送http请求
    resp, err := http.Get("http://www.cwnu.edu.cn/")
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    //读取响应数据
    body, err := ioutil.ReadAll(resp.Body)
    //解析 a标签里面的 href数据
    reg, _ := regexp.Compile(`<a.+href="(http.+?)"`)
    res := reg.FindAllStringSubmatch(string(body), -1)
    for idx := range res {
        fmt.Println(res[idx][1])
        //后续数据处理
    }
}

web

版本1

package main

import (
    "net/http"
)

func index(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte(`hello`))
}
func main() {
    http.HandleFunc(`/first`, index)
    http.ListenAndServe(":8080", nil)
}

alt

巴拉巴拉。。。✍

版本2

package main
import (
    "io/ioutil"
    "net/http"
    "os"
)
func index(w http.ResponseWriter, r *http.Request) {
    //读取html文件
    f, _ := os.Open(`./index.html`)
    //读取数据
    buf, _ := ioutil.ReadAll(f)
    //写入到响应
    w.Write(buf)

}
func main() {
    http.HandleFunc(`/first`, index)
    //静态文件访问 css img js 等
    http.Handle("/res/", http.StripPrefix("/res/", http.FileServer(http.Dir("./res"))))
    http.ListenAndServe(":8080", nil)
}

html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello</title>
</head>
<body>
    <div>index.html</div>
    <script src="/res/js.js"></script>
</body>
</html>

js 文件

alert("res js")

本文链接:https://www.paishouba.com/post/goweb-03-8.html

-- EOF --

Comments