本文目錄一覽:
- 1、golang echo(二)—請求與響應
- 2、Golang 網路編程絲綢之路 – TCP/UDP 地址解析
- 3、golang udp編程
- 4、Golang 綁定mac和ip地址,限制伺服器
- 5、如何使用Go語言實現遠程執行命令
- 6、Golang–獲取本地IP
golang echo(二)—請求與響應
上一章節介紹了使用echo啟動一個http伺服器並提供一個簡單的GET介面,這一章對請求與響應做一下詳細的講解。
了解請求與響應之前首先要知道ehco框架提供了一個Context介面,Context 表示當前 HTTP 請求的上下文,我們需要知道的是Context的實現結構體context,context中包含了請求(request)、響應(response)以及參數等結構體,context是一個內部結構體,但是對外提供了訪問的方法,我們可以在開發中使用context提供的方法做很多事情,比如獲取請求路徑、客戶端ip、請求參數等等。
request是包含了當前請求信息的結構體,我們從中可以獲取到前後端約定好的參數來作出相應的業務邏輯,這下面開始模擬請求
首先模擬一個添加用戶的POST請求,這裡使用了c.bind()這個方法,這個方法起到的作用是把表單參數或者JSON參數綁定至對應的結構體(這裡必須是指針類型),欄位需要一一對應,也就是說前端需要傳遞的表單或JSON參數名為name、age、gender才能綁定到結構體中。
接下來模擬一個GET請求用來獲取用戶信息
response是包含了返回信息的結構體,echo提供了多種類型的返回結果
上面編寫了處理請求的handler,這裡介紹一下如何把handler註冊到路由中,這裡對應的就是上面handler。
Golang 網路編程絲綢之路 – TCP/UDP 地址解析
TL;DR 在使用 Golang 編寫 TCP/UDP socket 的時候,第一步做的就是地址解析。
該函數返回的地址包含的信息如下:
TCPAddr 里, IP 既可以是 IPv4 地址,也可以是 IPv6 地址。 Port 就是埠了。 Zone 是 IPv6 本地地址所在的區域。
從返回結果看該函數的參數, network 指 address 的網路類型; address 指要解析的地址,會從中解析出我們想要的 IP , Port 和 Zone 。
從源碼中可以看出,參數 network 只能是如下四個值,否則會得到一個錯誤。
解析過程跟 ResolveTCPAddr 的一樣,不過得到的是 *UDPAddr 。
UDPAddr 包含的信息如下:
golang udp編程
用戶數據報協議(User Datagram Protocol,縮寫為UDP),又稱用戶數據報文協議,是一個簡單的面向數據報(package-oriented)的傳輸層協議,正式規範為RFC 768。
UDP只提供數據的不可靠傳遞,它一旦把應用程序發給網路層的數據發送出去,就不保留數據備份(所以UDP有時候也被認為是不可靠的數據報協議)。
UDP在IP數據報的頭部僅僅加入了復用和數據校驗。
由於缺乏可靠性且屬於非連接導向協議,UDP應用一般必須允許一定量的丟包、出錯和複製粘貼。
1 在接收udp包時,如果接收包時給定的buffer太小的話,就要自己解決粘包問題。
2 udp包的發送和接收不保證一定成功,不保證按正確順序抵達。
3 如果不允許丟包的情況出現的話,要有重發機制來保證,如:反饋機制確認。
服務端
客戶端
Golang 綁定mac和ip地址,限制伺服器
實際業務:go 二進位文件在私有化部署中,需要對客戶的伺服器mac和ip進行綁定,系統只能運行在綁定的伺服器上。把mac和ip地址配置到config中。
運行效果:系統可正常編譯,正常訪問,在用戶Auth介面進行核對。
//檢驗Mac和內網IP,測試環境不做校驗
func (c *CommonBase)CheckMacAndIp()error {
ipCfg :=g.Cfg().GetString(“machine.Ipaddr”)
macCfg :=g.Cfg().GetString(“machine.Macip”)
if ipCfg ==”127.0.0.1″ {
return nil
}
macArray,_ :=gipv4.GetMacArray()
if len(macArray) ==0 {
return gerror.New(“mac地址獲取失敗”)
}
if garray.NewStrArrayFrom(macArray).Contains(macCfg) ==false {
return gerror.New(“示授權的應用MAC,請聯繫”)
}
ipArray,_ :=gipv4.GetIpArray()
ipIntranetArray,_ :=gipv4.GetIntranetIpArray()
if len(ipArray) ==0 len(ipIntranetArray) ==0 {
return gerror.New(“ip地址獲取失敗”)
}
if garray.NewStrArrayFrom(ipArray).Merge(ipIntranetArray).Contains(ipCfg) ==false {
return gerror.New(“示授權的應用IP,請聯繫”)
}
return nil
}
項目使用GoFrame框架1.6。考慮到客戶可能會對內存數據做分析破解,可以把mac和ip地址做AES加密。
如何使用Go語言實現遠程執行命令
一般命令
所謂一般命令,就是在一定時間內會執行完的命令。比如 grep, cat 等等。 執行命令的步驟是:連接,執行,獲取結果
連接
連接包含了認證,可以使用 password 或者 sshkey 2種方式來認證。下面的示例為了簡單,使用了密碼認證的方式來完成連接。
import (
“fmt”
“time”
“golang.org/x/crypto/ssh”
)
func connect(user, password, host string, port int) (*ssh.Session, error) {
var (
auth []ssh.AuthMethod
addr string
clientConfig *ssh.ClientConfig
client *ssh.Client
session *ssh.Session
err error
)
// get auth method
auth = make([]ssh.AuthMethod, 0)
auth = append(auth, ssh.Password(password))
clientConfig = ssh.ClientConfig{
User: user,
Auth: auth,
Timeout: 30 * time.Second,
}
// connet to ssh
addr = fmt.Sprintf(“%s:%d”, host, port)
if client, err = ssh.Dial(“tcp”, addr, clientConfig); err != nil {
return nil, err
}
// create session
if session, err = client.NewSession(); err != nil {
return nil, err
}
return session, nil
}
連接的方法很簡單,只要提供登錄主機的 用戶*, *密碼*, *主機名或者IP*, *SSH埠
執行,命令獲取結果
連接成功後,執行命令很簡單
import (
“fmt”
“log”
“os”
“time”
“golang.org/x/crypto/ssh”
)
func main() {
session, err := connect(“root”, “xxxxx”, “127.0.0.1”, 22)
if err != nil {
log.Fatal(err)
}
defer session.Close()
session.Run(“ls /; ls /abc”)
}
上面代碼運行之後,雖然命令正常執行了,但是沒有正常輸出的結果,也沒有異常輸出的結果。 要想顯示結果,需要將 session 的 Stdout 和 Stderr 重定向 修改 func main 為如下:
func main() {
session, err := connect(“root”, “xxxxx”, “127.0.0.1”, 22)
if err != nil {
log.Fatal(err)
}
defer session.Close()
session.Stdout = os.Stdout
session.Stderr = os.Stderr
session.Run(“ls /; ls /abc”)
}
這樣就能在屏幕上顯示正常,異常的信息了。
互動式命令
上面的方式無法遠程執行互動式命令,比如 top , 遠程編輯一個文件,比如 vi /etc/nginx/nginx.conf 如果要支持互動式的命令,需要當前的terminal來接管遠程的 PTY。
func main() {
session, err := connect(“root”, “olordjesus”, “dockers.iotalabs.io”, 2210)
if err != nil {
log.Fatal(err)
}
defer session.Close()
fd := int(os.Stdin.Fd())
oldState, err := terminal.MakeRaw(fd)
if err != nil {
panic(err)
}
defer terminal.Restore(fd, oldState)
// excute command
session.Stdout = os.Stdout
session.Stderr = os.Stderr
session.Stdin = os.Stdin
termWidth, termHeight, err := terminal.GetSize(fd)
if err != nil {
panic(err)
}
// Set up terminal modes
modes := ssh.TerminalModes{
ssh.ECHO: 1, // enable echoing
ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
}
// Request pseudo terminal
if err := session.RequestPty(“xterm-256color”, termHeight, termWidth, modes); err != nil {
log.Fatal(err)
}
session.Run(“top”)
}
Golang–獲取本地IP
Golang獲取本地IP地址方法,目前了解兩種,記錄如下:
方法1:
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/232044.html