Go語言socket網路編程(一)
一、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)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/282672.html
標籤:區塊鏈
