一、IP查找与转换
1、获取ip与电脑信息的函数信息
str := net.JoinHostPort("127.0.0.1", "8080")
str1 := net.JoinHostPort("::1", "8080") //端口,IP合并
host, port, _ := net.SplitHostPort("127.0.0.1:8080") //端口,IP分离
Name, _ := net.LookupAddr("127.0.0.1") //查询主机名
addr, _ := net.LookupAddr("61.135.169.121") //查询域名,返回的是切片
fmt.Println(net.LookupHost("www.baidu.com"))
log.Println(str) //str
log.Println(str1) //str
log.Println(host) //str
log.Println(port) //str
log.Println(Name) //str
log.Println(addr) //str
2、有些库必须使用IP格式,所以需要返回IP形式
ip := net.ParseIP("127.0.0.1") //通过字符串转换为IP地址
fmt.Printf("%T,%v", ip, ip)
addrs, _ := net.LookupIP("www.baidu.com") //通过域名找IP
log.Println(addrs)
3、判断IP地址是否在同一网段
ip, ipnet, _ := net.ParseCIDR("192.168.10.110/24")
log.Println(ip)
log.Println(ipnet)
newIp := net.ParseIP("192.168.12.12")
bool := ipnet.Contains(newIp)
log.Println(bool)
4、获取主机相关连接
package main
import (
"fmt"
_ "fmt"
"net"
)
func main() {
addrs, _ := net.InterfaceAddrs() //获取当前机器的网络名,字符串格式的IP地址
for _, addr := range addrs {
fmt.Println(addr.Network(), addr.String())
}
}
5、获取系统网络接口
func main() {
ifc, _ := net.Interfaces()
for _, v := range ifc {
fmt.Println(v)
}
}
二、TCP连接
1、交互聊天
(1)服务器
package main
import (
"bufio"
"fmt"
"log"
"net"
"os"
)
func main() {
log.SetPrefix("main")
file, err := os.OpenFile("Server.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.ModePerm)
defer file.Close()
if err != nil {
log.Fatal("OpenFile:", err)
}
log.SetOutput(file)
listen, err := net.Listen("tcp", "127.0.0.1:8888")
if err != nil {
log.Println(err)
}
conn, err := listen.Accept()
if err != nil {
log.Println("Accept", err)
}
defer conn.Close()
for {
data := make([]byte, 1024)
reader := bufio.NewReader(conn)
n, err := reader.Read(data)
if err != nil {
log.Println("buf", err)
break
}
fmt.Println(string(data[0:n]))
}
}
(2)客户端
package main
import (
"bufio"
"fmt"
"log"
"net"
"os"
)
func main() {
log.SetPrefix("client")
file, err := os.OpenFile("Client.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0777)
if err != nil {
log.Fatal(err)
}
log.SetOutput(file)
conn, err := net.Dial("tcp", "127.0.0.1:8888")
defer conn.Close()
if err != nil {
log.Println("Dial", err)
}
scan := bufio.NewScanner(os.Stdin)
fmt.Println("请输入你要发送的消息:")
scan.Scan() //扫描
fmt.Fprint(conn, scan.Text())
}
2、服务器文件指令实现
三、UDP连接
1、Server端聊天
package main
import (
"fmt"
"log"
"net"
"os"
)
func main() {
file, err := os.Create("ServerLog.log")
log.SetPrefix("server:")
if err != nil {
log.Fatal(err)
}
log.SetOutput(file)
addr := "127.0.0.1:8080"
packetConn, err := net.ListenPacket("udp", addr) //使用UDP的方式监听
defer packetConn.Close()
if err != nil {
log.Println(err)
}
ctx := make([]byte, 1024)
for {
n, addr, err := packetConn.ReadFrom(ctx)
if err != nil {
log.Println(err)
}
fmt.Println(addr.String()) //传输过来的地址
fmt.Println(string(ctx[0:n]))
packetConn.WriteTo([]byte("测试UDP传输回去"), addr)
}
}
2、客户端聊天
package main
import (
"fmt"
"log"
"net"
"os"
)
func main() {
var str string
file, err := os.Create("ClientErr.log")
if err != nil {
log.Fatal(err)
}
log.SetOutput(file)
conn, err := net.Dial("udp", "127.0.0.1:8080")
if err != nil {
log.Println(err)
}
fmt.Scanln(&str)
fmt.Fprintf(conn, "%s", str)
ctx := make([]byte, 1024)
n, err := conn.Read(ctx)
if err != nil {
log.Println(err)
}
fmt.Println(string(ctx[0:n]))
}
四、HTTP协议
1、简单的web服务三步骤
package main
import (
"fmt"
"net/http"
"time"
)
//Http的三步骤
//1、处理器函数
//2、绑定URL关系
//3、启动Server服务
func main() {
//处理器函数
timeFunc := func(response http.ResponseWriter, request *http.Request) {
fmt.Println(request)
now := time.Now().Format("2006-01-02 15:04:05")
fmt.Fprint(response, now)
}
//绑定URL关系
http.HandleFunc("/home/", timeFunc) //第一个参数为路径,第二个参数为匿名函数
//启动web服务
http.ListenAndServe(":9999", nil)
}
2、三部曲读取文件内容
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
//Http的三步骤
//1、处理器函数
//2、绑定URL关系
//3、启动Server服务
func main() {
http.HandleFunc("/", func(response http.ResponseWriter, request *http.Request) {
ctx, err := ioutil.ReadFile("HTTP/index.html")
if err != nil {
fmt.Fprintf(response, "%s", "网页读取出现错误")
fmt.Println(err)
fmt.Println(string(ctx))
} else {
fmt.Fprintf(response, "%s", string(ctx))
}
})
http.ListenAndServe("127.0.0.1:9999", nil)
}
3、面向对象实现
package main
import (
"fmt"
"net/http"
"time"
)
//使用对象接口的思维来维护
type TimeHandler struct {
} //定义结构体来实现接口
func (h *TimeHandler) ServeHTTP(response http.ResponseWriter, request *http.Request) {
now := time.Now().Format("2006-01-02 15:04:05")
fmt.Fprint(response, now)
}
func main() {
http.Handle("/time/", &TimeHandler{
}) //传入实现结构的方法
http.ListenAndServe("127.0.0.1:9999", nil)
}
4、获取报文信息
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) {
fmt.Println(req.Method, req.URL, req.Proto)
fmt.Println(req.Header) //获取请求头的信息
fmt.Println(req.Header.Get("User-Agent"))
})
http.ListenAndServe("127.0.0.1:9999", nil)
}
5、参数解析
(1) Post参数解析
package main
import (
"fmt"
"net/http"
)
//解析参数
//http协议
//post获取数据
func main() {
http.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) {
fmt.Println(req.PostFormValue("a")) //获取post的a值
req.ParseForm()
fmt.Println(req.PostForm) //只包含请求体数据
})
http.ListenAndServe("127.0.0.1:9999", nil)
}
(2)Get参数解析
package main
import (
"fmt"
"net/http"
)
//解析参数
//http协议
//post获取数据
func main() {
http.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) {
req.ParseForm()
fmt.Println(req.Form)
fmt.Println(req.Form.Get("a")) //获取a的值
fmt.Println(req.Form["a"]) //获取a的值
fmt.Println(req.FormValue("a")) //获取a的值
fmt.Println(req.PostForm) //只包含请求体数据
})
http.ListenAndServe("127.0.0.1:9999", nil)
}
(3)上传文件,获取文件相关信息
package main
import (
"fmt"
"io"
"net/http"
"os"
)
//上传文件 =>multipart/form-data
func main() {
http.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) {
//第一种方式
//req.ParseMultipartForm(1024 * 1024) //解析提交内容
//fmt.Println(req.MultipartForm)
//file, err := req.MultipartForm.File["a"][0].Open()
//if err != nil {
// fmt.Println(err)
//}
//io.Copy(os.Stdout, file)
//第二种方式
file, header, _ := req.FormFile("a")
fmt.Println(header.Filename) //文件名
fmt.Println(header.Size) //文件大小
fmt.Println(header.Header) //文件头的相关信息
io.Copy(os.Stdout, file)
})
http.ListenAndServe("127.0.0.1:8888", nil)
}
6、json格式获取
package main
import (
"encoding/json"
"fmt"
"net/http"
)
//上传文件 =>multipart/form-data
func main() {
http.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) {
//io.Copy(os.Stdout, req.Body) //读取请求头的数据,流只能解析一次
decoder := json.NewDecoder(req.Body) //解析流
var info map[string]interface{
}
decoder.Decode(&info) //将解析的coder对象放在map中(里面可以放任意接口)
fmt.Println(info)
fmt.Println(info["a"])
})
http.ListenAndServe("127.0.0.1:8888", nil)
}
7、Cookie
package main
import (
"net/http"
"strconv"
"strings"
)
func SetCook(cookie string) map[string]string {
cookieMap := make(map[string]string)
vals := strings.Split(cookie, ";") //切分cookie
for _, val := range vals {
cook := strings.Split(val, "=") //将cookie分为map类型
cookieMap[strings.TrimSpace(cook[0])] = strings.TrimSpace(cook[1])
}
return cookieMap
}
//上传文件 =>multipart/form-data
func main() {
http.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) {
cookieMap := SetCook(req.Header.Get("cookie")) //处理cookie函数
counter := 0
if v, err := strconv.Atoi(cookieMap["counter"]); err == nil {
counter = v
}
counterCookie := &http.Cookie{
Name: "counter",
Value: strconv.Itoa(counter + 1),
HttpOnly: true,
} //当访问这个网页的时候,服务器返回一个cookie回去
http.SetCookie(resp, counterCookie) //将cookie的值使用响应体的方式返回
})
http.ListenAndServe("127.0.0.1:9999", nil)
}
8、重镜像
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/home/", func(resp http.ResponseWriter, req *http.Request) {
//fmt.Fprint(resp, "首页")//当前页面
//进行重镜像
http.Redirect(resp, req, "/Login/", 302) //将网址重定向到login中
})
http.HandleFunc("/Login/", func(resp http.ResponseWriter, req *http.Request) {
fmt.Fprint(resp, "登录")
})
http.ListenAndServe("127.0.0.1:9999", nil)
}
9、文件服务器(类似Nginx)
package main
import (
"net/http"
)
func main() {
http.Handle("/static/", http.FileServer(http.Dir("./")))
//第一种
http.Handle("/static2/", http.StripPrefix("/static2/", http.FileServer(http.Dir("./www"))))
//第二种
http.Handle("/www/", http.FileServer(http.Dir(".")))
http.ListenAndServe("127.0.0.1:9999", nil)
}
10、发送请求
package main
import (
"bytes"
"fmt"
"io"
"net/http"
"net/url"
"os"
)
//发送相关请求
func main() {
//通过Get发送请求
response, err := http.Get("http://localhost:9999/?a=1&b=2")
if err != nil {
fmt.Println(err)
} else {
//fmt.Println(response.Proto, response.StatusCode, response.Status)
//fmt.Println(response.Header)
io.Copy(os.Stdout, response.Body)
}
//通过post发送请求
buf := bytes.NewBufferString(`{"name":12}`) //创建一个缓冲对象
resp, err := http.Post("localhost:9999", "application/json", buf)
fmt.Println(resp, err)
//通过PostForm请求
parms := url.Values{
} //创建map映射
parms.Add("name", "tom") //添加映射
resp, err := http.PostForm("http://localhost:8888", parms)
fmt.Println(resp, err)
}