常用标签
注释
标题 h1~h6
段落 p
超链接 a
图片 img
表单 form
input: text/password/radio/checkbox/file/date/datetime/url/submit/hidden
textarea
select/option
按钮 button
表格 table/thead/tbody/tr/td/th
列表 ol/ul/li
块 div/span
…….
<!DOCTYPE html>
>
>
-8">
>我的第一个页面 >
>
>
我叫aa
://www.baidu.com" target="_blank">百度>
://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1585021686&di=90e0a79359a4f6aa14cc1dc1c7a81200&src=http://gss0.baidu.com/7Po3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/b999a9014c086e06b273602204087bf40bd1cb84.jpg">
>
>
>
>姓名 >
>联系方式 >
>
>
>
>
>aa >
>133888 >
>
>
>
>
>
(1)应用开发
http包提供了HTTP服务器和客户端的开发接口,内置web服务器
针对web服务端开发流程为
定义处理器/处理器函数
接收用户数据
返回信息
启动web服务器
(2)常用函数
ListenAndServer:使用http协议启动web服务
Handle:定义url对应处理器
HandleFunc:定义url对应处理器函数
Redirect:重定向
SetCookie:设置Cookie
FileServer: 创建静态文件处理器
(3)常用结构体
①Request
常用属性
Method: 请求方式
URL:请求的URL
Proto:请求协议
Header:请求头
ContentLength:请求体字节数量
Body:请求体流对象
Form:获取提交的所有数据,需要手动调用ParseForm
PostForm:获取所有body中提交的数据(application/x-www-form-urlencoded) ,需要手动调用ParseForm
MultipartForm:获取所有body中提交的数据(multipart/form-data) ,需要手动调用ParseMutipartForm
常用方法
ParseForm:解析提交的数据(url&body[application/x-www-form-urlencode])
FormValue:根据名称获取提交的数据,自动调用ParseForm
PostFormValue:根据名称从body中获取提交的数据,自动调用ParseForm
ParseMultipartForm:解析提交的数据(url*body[multipart/form-data])
FormFile:根据名称从body中获取提交的文件数据流对象,自动调用ParseMutipartForm,ParseForm
②Reponse
常用属性
Status:响应状态
StatusCode:响应状态码
Proto:协议信息
Header:响应头
ContentLength:响应体字节数量
Body:响应体流对象
常用方法
Cookies:cookie信息
Location:location信息
Write:将响应体写入输出流
常用接口
ResponseWriter
常用方法:
Write:写入响应体
Header:写入响应头信息
WriteHeader:写入请求行状态码(在调用后不能Write和设置Header信息)
常用结构体
Header
常用方法
Set:设置头信息
Add:添加头信息
Del:删除头信息
Get:获取头信息
//server
package main
import (
"fmt"
"net"
"os"
)
func main() {
addr := "0.0.0.0:9999"
server,err := net.ListenPacket("udp",addr)
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
for {
bytes := make([]byte,1024)
n,addr,err := server.ReadFrom(bytes)
fmt.Println(n,addr,err,string(bytes))
//写消息给谁
server.WriteTo([]byte("hi"),addr)
}
}
//client
package main
import (
"fmt"
"net"
"os"
"time"
)
func main() {
addr := "192.168.0.105:9999"
conn,err := net.Dial("udp",addr)
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
defer conn.Close()
fmt.Fprintf(conn,"Time %s:",time.Now().Format("2016-01-02 "))
bytes := make([]byte,1024)
n,err := conn.Read(bytes)
fmt.Println(n,err,string(bytes[:n]))
}
package main
import (
"fmt"
"net"
)
func main() {
//拼接ip+端口
fmt.Println(net.JoinHostPort("0.0.0.0","8888"))
//吧ip:端口 拆分为 ip 端口
fmt.Println(net.SplitHostPort("192.168.1.1:8888"))
//根据ip查找对应主机
fmt.Println(net.LookupAddr("39.156.69.79" ))
//根据域名查找对应主机ip
fmt.Println(net.LookupHost("www.baidu.com"))
//带掩码格式 打印你的ip 以及你的网络子网范围
fmt.Println(net.ParseCIDR("192.168.1.1/24"))
//可以解析ipv4 跟ipv6 返回一个IP类型的 ip的类型是[]byte
ip01 := net.ParseIP("::1")
ip02 := net.ParseIP("192.168.1.100")
//解析失败会返回一个nil
fmt.Println(ip01)
fmt.Println(ip02)
//返LookupIP返回的是一个ip的集合 也就是切片 和err
ip03 ,err:= net.LookupIP("www.baidu.com")
fmt.Println(ip03,err)
ip,ipnet,err := net.ParseCIDR("192.168.1.1/24")
//判断ip是否在 cidr范围内
fmt.Println(ipnet.Contains(net.ParseIP("192.168.1.40")))
fmt.Println(ipnet.Contains(net.ParseIP("193.168.1.40")))
fmt.Println(ipnet.Network())
fmt.Println(ip)
addrs ,_ := net.InterfaceAddrs()
for _,addr := range addrs {
fmt.Println(addr.String(),addr.Network())
}
inters,_ := net.Interfaces()
for _,inter := range inters{
fmt.Println(inter.Name,inter.Index,inter.Flags,inter.MTU,inter.HardwareAddr)
fmt.Println(inter.Addrs())
fmt.Println(inter.MulticastAddrs())
}
}
//server
package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func Time(w http.ResponseWriter,r *http.Request) {
fmt.Fprintf(w,"Time:%d",time.Now().Unix())
}
type Test03 struct {}
//处理器
func (a Test03) ServeHTTP(w http.ResponseWriter,r *http.Request){
fmt.Fprintf(w,"Time: %s",time.Now().Format("2006-1-2 15:02:01"))
}
func main() {
//定义处理器函数
http.HandleFunc("/test", func(w http.ResponseWriter,r *http.Request) {
w.Write([]byte("hello"))
})
http.HandleFunc("/test02",Time)
http.Handle("/test03",Test03{})
http.HandleFunc("/test04", func(w http.ResponseWriter,r *http.Request) {
//请求行
fmt.Println(r.UserAgent())
fmt.Println(r.Referer())
fmt.Println(r.Method,r.URL,r.Proto)
//请求头
fmt.Println(r.Header)
//请求体
//bytes := make([]byte,1024)
//n,_ := r.Body.Read(bytes)
//fmt.Println(string(bytes[:n]))
//把r.body copy至标准输入 里面也是有循环判断是否io.eof
io.Copy(os.Stdin,r.Body)
w.Write([]byte("Request"))
})
//启动一个文件服务器
//表示当前目录所有
http.Handle("/",http.FileServer(http.Dir(".")))
//在当前目录下的file文件夹中
//http.Handle("/file",http.FileServer(http.Dir(".")))
err := http.ListenAndServe("0.0.0.0:9999",nil)
if err != nil {
fmt.Println(err)
}
}
//client-v1
package main
import (
"bytes"
"fmt"
"io"
"net/http"
"net/url"
"os"
)
func main() {
url01 := "http://127.0.0.1:9999/test04"
//get用于获取 //post用于修改
response ,err := http.Get(url01)
if err == nil {
//协议以及状态信息
fmt.Println(response.Proto,response.Status)
//头部信息
fmt.Println(response.Header)
//请求体
io.Copy(os.Stdout,response.Body)
fmt.Println()
}
json := bytes.NewReader([]byte(`{"name" : "kk","password" : "12345}`))
response,err = http.Post(url01,"application/json",json)
if err == nil {
//协议以及状态信息
fmt.Println(response.Proto,response.Status)
//头部信息
fmt.Println(response.Header)
//请求体
io.Copy(os.Stdout,response.Body)
fmt.Println()
}
params := make(url.Values)
params.Add("name","k")
params.Add("password","123")
response,err = http.PostForm(url01,params)
if err == nil {
//协议以及状态信息
fmt.Println(response.Proto,response.Status)
//头部信息
fmt.Println(response.Header)
//请求体
io.Copy(os.Stdout,response.Body)
fmt.Println()
}
}
//client-v2
package main
import (
"crypto/tls"
"fmt"
"io"
"net/http"
"os"
)
func main() {
url := "http://localhost:9999/test04"
//delete 表示删除
request,_ := http.NewRequest("DELETE",url,nil)
//这个配置true可以跳过认证 比如某些自作证书的https网站 不信任的 可以跳过
transport := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify:true}}
client := &http.Client{Transport:transport}
response,err := client.Do(request)
if err == nil {
//协议以及状态信息
fmt.Println(response.Proto,response.Status)
//头部信息
fmt.Println(response.Header)
//请求体
io.Copy(os.Stdout,response.Body)
fmt.Println()
}
}
package main
import (
"bytes"
"fmt"
"github.com/PuerkitoBio/goquery"
"io/ioutil"
"strings"
)
func main() {
//url := "https://www.zhipin.com/c101010100/y_6-s_304/?query=devops&ka=sel-scale-304"
//request,_ := http.NewRequest("GET",url,nil)
//boss需要日换cokey
//request.Header.Set("cookie","lastCity=101010100; t=th0PstY21h4TF20h; wt=th0PstY21h4TF20h; __c=1585034869; __g=-; __l=l=%2Fwww.zhipin.com%2Fweb%2Fgeek%2Frecommend&r=https%3A%2F%2Fcn.bing.com%2F&friend_source=0&friend_source=0; Hm_lvt_194df3105ad7148dcf2b98a91b5e727a=1584923226,1584946519,1585017679,1585034876; Hm_lpvt_194df3105ad7148dcf2b98a91b5e727a=1585047125; __zp_stoken__=dd77Ir6UHeMCkG9IDXlYw0Is19q0%2FX2QYixRWRtlZY0JEQiqcjN4cDzoSatQk98YCfA%2Fnd%2BgY0uctWDLVmAa9TKIyP0zN2OIOOJq6yUL2ADAigua4G89LJ7fToCDutRAlwPV; __zp_sseed__=JACbDVsIkXRju/l3PNgAstDGEk8JM+S+l5MjXRhUBcc=; __zp_sname__=ea550e23; __zp_sts__=1585047371082; __a=48396892.1584923226.1585009959.1585034869.73.10.25.73")
//client := &http.Client{}
//response,_ := client.Do(request)
//document ,_:= goquery.NewDocumentFromResponse(response)
//readfile 返回值是一个[]byte
cxt,_ := ioutil.ReadFile("job.html")
//因为NewDocumentFromReader 参数是一个reader 所以需要给[]byte 封装一个reader
reader := bytes.NewReader(cxt)
document,_ := goquery.NewDocumentFromReader(reader)
//fmt.Println(err,document)
//fmt.Println(document.Html())
document.Find("div.job-primary").Each(func(i int, selection *goquery.Selection) {
fmt.Println(strings.Repeat("-",20))
//fmt.Println(selection.Html())
fmt.Println(selection.Find("div.info-company > div.company-text > h3 > a").Text())
tagA := selection.Find("div.info-primary> div.primary-wrapper >a ")
fmt.Println(tagA.Find("div.job-title > span.job-name").Text())
fmt.Println(tagA.Find("div.job-limit > span.red").Text())
})
}
//client
package main
import (
"fmt"
"net/rpc/jsonrpc"
"test/object"
)
func main() {
//获取连接
client,err := jsonrpc.Dial("tcp","127.0.0.1:9999")
if err == nil {
//定义请求对象/响应对象
request := object.Request{5,10}
var response object.Response
//调用远程方法
err := client.Call("Calc.Sum",&request,&response)
if err == nil {
fmt.Println(response.Result)
}else {
fmt.Println(err)
}
}else {
fmt.Println(err)
}
}
//main
package main
import (
"fmt"
"net"
"net/rpc"
"net/rpc/jsonrpc"
"test/object"
)
func main() {
//注册RPC服务
rpc.Register(&object.Calc{})
server ,err := net.Listen("tcp",":9999")
if err != nil {
fmt.Println(err)
}
defer server.Close()
for {
client,err := server.Accept()
if err == nil {
jsonrpc.ServeConn(client) //使用jsonrpc处理客户端连接
}
}
}
//rpc
package object
import "fmt"
type Request struct {
Left int
Right int
}
type Response struct {
Result int
}
type Calc struct {}
func (c *Calc) Sum(r *Request , rp *Response) error{
fmt.Println("Sum",r.Left,r.Right)
rp.Result = r.Left + r.Right
return nil
}