网络操作(计算机网络相关知识可以利用此包实践)
net
net
包提供了可移植的网络I/O
接口,包括TCP/IP
、UDP
、域名解析和Unix
域socket
。- 本包提供了对网络原语的访问,大部分使用者只需要
Dial
、Listen
和Accept
函数提供的基本接口;以及相关的Conn
和Listener
接口。
过程
- 服务端程序
Listen
监听某个端口,等待客户端程序的连接请求Accept
。 - 客户端程序
Dial
申请连接。 - 服务端程序 处理连接请求并建立网络连接
Conn
- 双方在
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/查看效果
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()
}
浏览器
控制台
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)
}
巴拉巴拉。。。✍
版本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("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
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="/static/js.js"></script>
</body>
</html>
js 文件
alert("res js")
Comments