# Netutil netutil 网络包支持获取 ip 地址,发送 http 请求。
## 源码: - [https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go) - [https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go)
## 用法: ```go import ( "github.com/duke-git/lancet/v2/netutil" ) ```
## 目录 - [ConvertMapToQueryString](#ConvertMapToQueryString) - [EncodeUrl](#EncodeUrl) - [GetInternalIp](#GetInternalIp) - [GetIps](#GetIps) - [GetMacAddrs](#GetMacAddrs) - [GetPublicIpInfo](#GetPublicIpInfo) - [GetRequestPublicIp](#GetRequestPublicIp) - [IsPublicIP](#IsPublicIP) - [IsInternalIP](#IsInternalIP) - [HttpRequest](#HttpRequest) - [HttpClient](#HttpClient) - [SendRequest](#SendRequest) - [DecodeResponse](#DecodeResponse) - [StructToUrlValues](#StructToUrlValues) - [HttpGetDeprecated](#HttpGet) - [HttpDeleteDeprecated](#HttpDelete) - [HttpPostDeprecated](#HttpPost) - [HttpPutDeprecated](#HttpPut) - [HttpPatchDeprecated](#HttpPatch) - [ParseHttpResponse](#ParseHttpResponse) - [DownloadFile](#DownloadFile) - [UploadFile](#UploadFile) - [IsPingConnected](#IsPingConnected) - [IsTelnetConnected](#IsTelnetConnected) - [IsTelnetConnected](#IsTelnetConnected) - [BuildUrl](#BuildUrl) - [AddQueryParams](#AddQueryParams)
## 文档 ### ConvertMapToQueryString

将map转换成http查询字符串.

函数签名: ```go func ConvertMapToQueryString(param map[string]any) string ``` 示例:[运行](https://go.dev/play/p/jnNt_qoSnRi) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/netutil" ) func main() { var m = map[string]any{ "c": 3, "a": 1, "b": 2, } qs := netutil.ConvertMapToQueryString(m) fmt.Println(qs) // Output: // a=1&b=2&c=3 } ``` ### EncodeUrl

编码url query string的值

函数签名: ```go func EncodeUrl(urlStr string) (string, error) ``` 示例:[运行](https://go.dev/play/p/bsZ6BRC4uKI) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/netutil" ) func main() { urlAddr := "http://www.lancet.com?a=1&b=[2]" encodedUrl, err := netutil.EncodeUrl(urlAddr) if err != nil { fmt.Println(err) } fmt.Println(encodedUrl) // Output: // http://www.lancet.com?a=1&b=%5B2%5D } ``` ### GetInternalIp

获取内部ip

函数签名: ```go func GetInternalIp() string ``` 示例:[运行](https://go.dev/play/p/fxnna_LLD9u) ```go package main import ( "fmt" "net" "github.com/duke-git/lancet/v2/netutil" ) func main() { internalIp := netutil.GetInternalIp() ip := net.ParseIP(internalIp) fmt.Println(ip) // Output: // 192.168.1.9 } ``` ### GetIps

获取ipv4地址列表

函数签名: ```go func GetIps() []string ``` 示例:[运行](https://go.dev/play/p/NUFfcEmukx1) ```go package main import ( "fmt" "net" "github.com/duke-git/lancet/v2/netutil" ) func main() { ips := netutil.GetIps() fmt.Println(ips) // Output: // [192.168.1.9] } ``` ### GetMacAddrs

获取mac地址列

函数签名: ```go func GetMacAddrs() []string { ``` 示例:[运行](https://go.dev/play/p/Rq9UUBS_Xp1) ```go package main import ( "fmt" "net" "github.com/duke-git/lancet/v2/netutil" ) func main() { macAddrs := netutil.GetMacAddrs() fmt.Println(macAddrs) // Output: // [18:31:bf:09:d1:56 76:ee:2a:e6:2e:0f 74:ee:2a:e6:2e:0f 74:ee:2a:e6:2e:0f] } ``` ### GetPublicIpInfo

获取公网ip信息

函数签名: ```go func GetPublicIpInfo() (*PublicIpInfo, error) type PublicIpInfo struct { Status string `json:"status"` Country string `json:"country"` CountryCode string `json:"countryCode"` Region string `json:"region"` RegionName string `json:"regionName"` City string `json:"city"` Lat float64 `json:"lat"` Lon float64 `json:"lon"` Isp string `json:"isp"` Org string `json:"org"` As string `json:"as"` Ip string `json:"query"` } ``` 示例:[运行](https://go.dev/play/p/YDxIfozsRHR) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/netutil" ) func main() { publicIpInfo, err := netutil.GetPublicIpInfo() if err != nil { fmt.Println(err) } fmt.Println(publicIpInfo) } ``` ### GetRequestPublicIp

获取http请求ip

函数签名: ```go func GetRequestPublicIp(req *http.Request) string ``` 示例:[运行](https://go.dev/play/p/kxU-YDc_eBo) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/netutil" ) func main() { ip := "36.112.24.10" request := http.Request{ Method: "GET", Header: http.Header{ "X-Forwarded-For": {ip}, }, } publicIp := netutil.GetRequestPublicIp(&request) fmt.Println(publicIp) // Output: // 36.112.24.10 } ``` ### IsPublicIP

判断ip是否是公共ip

函数签名: ```go func IsPublicIP(IP net.IP) bool ``` 示例:[运行](https://go.dev/play/p/nmktSQpJZnn) ```go package main import ( "fmt" "net" "github.com/duke-git/lancet/v2/netutil" ) func main() { ip1 := netutil.IsPublicIP(net.ParseIP("127.0.0.1")) ip2 := netutil.IsPublicIP(net.ParseIP("192.168.0.1")) ip3 := netutil.IsPublicIP(net.ParseIP("36.112.24.10")) fmt.Println(ip1) fmt.Println(ip2) fmt.Println(ip3) // Output: // false // false // true } ``` ### IsInternalIP

判断ip是否是局域网ip.

函数签名: ```go func IsInternalIP(IP net.IP) bool ``` 示例:[运行](https://go.dev/play/p/sYGhXbgO4Cb) ```go package main import ( "fmt" "net" "github.com/duke-git/lancet/v2/netutil" ) func main() { ip1 := netutil.IsInternalIP(net.ParseIP("127.0.0.1")) ip2 := netutil.IsInternalIP(net.ParseIP("192.168.0.1")) ip3 := netutil.IsInternalIP(net.ParseIP("36.112.24.10")) fmt.Println(ip1) fmt.Println(ip2) fmt.Println(ip3) // Output: // true // true // false } ``` ### HttpRequest

HttpRequest用于抽象HTTP请求实体的结构

函数签名: ```go type HttpRequest struct { RawURL string Method string Headers http.Header QueryParams url.Values FormData url.Values Body []byte } ``` 示例:[运行](https://go.dev/play/p/jUSgynekH7G) ```go package main import ( "fmt" "net" "github.com/duke-git/lancet/v2/netutil" ) func main() { header := http.Header{} header.Add("Content-Type", "multipart/form-data") postData := url.Values{} postData.Add("userId", "1") postData.Add("title", "testItem") request := &netutil.HttpRequest{ RawURL: "https://jsonplaceholder.typicode.com/todos", Method: "POST", Headers: header, FormData: postData, } } ``` ### HttpClient

HttpClient是用于发送HTTP请求的结构体。它可以用一些配置参数或无配置实例化.

函数签名: ```go type HttpClient struct { *http.Client TLS *tls.Config Request *http.Request Config HttpClientConfig } type HttpClientConfig struct { SSLEnabled bool TLSConfig *tls.Config Compressed bool HandshakeTimeout time.Duration ResponseTimeout time.Duration Verbose bool } func NewHttpClient() *HttpClient func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient ``` 示例:[运行](https://go.dev/play/p/jUSgynekH7G) ```go package main import ( "fmt" "net" "time" "github.com/duke-git/lancet/v2/netutil" ) func main() { httpClientCfg := netutil.HttpClientConfig{ SSLEnabled: true, HandshakeTimeout:10 * time.Second } httpClient := netutil.NewHttpClientWithConfig(&httpClientCfg) } ``` ### SendRequest

HttpClient发送http请求

函数签名: ```go func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error) ``` 示例:[运行](https://go.dev/play/p/jUSgynekH7G) ```go package main import ( "fmt" "net" "time" "github.com/duke-git/lancet/v2/netutil" ) func main() { request := &netutil.HttpRequest{ RawURL: "https://jsonplaceholder.typicode.com/todos/1", Method: "GET", } httpClient := netutil.NewHttpClient() resp, err := httpClient.SendRequest(request) if err != nil || resp.StatusCode != 200 { return } type Todo struct { UserId int `json:"userId"` Id int `json:"id"` Title string `json:"title"` Completed bool `json:"completed"` } var todo Todo err = httpClient.DecodeResponse(resp, &todo) if err != nil { return } fmt.Println(todo.Id) // Output: // 1 } ``` ### DecodeResponse

解析http响应体到目标结构体

函数签名: ```go func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error ``` 示例:[运行](https://go.dev/play/p/jUSgynekH7G) ```go package main import ( "fmt" "net" "time" "github.com/duke-git/lancet/v2/netutil" ) func main() { request := &netutil.HttpRequest{ RawURL: "https://jsonplaceholder.typicode.com/todos/1", Method: "GET", } httpClient := netutil.NewHttpClient() resp, err := httpClient.SendRequest(request) if err != nil || resp.StatusCode != 200 { return } type Todo struct { UserId int `json:"userId"` Id int `json:"id"` Title string `json:"title"` Completed bool `json:"completed"` } var todo Todo err = httpClient.DecodeResponse(resp, &todo) if err != nil { return } fmt.Println(todo.Id) // Output: // 1 } ``` ### StructToUrlValues

将结构体转为url values, 仅转化结构体导出字段并且包含`json` tag

函数签名: ```go func StructToUrlValues(targetStruct any) url.Values ``` 示例:[运行](https://go.dev/play/p/pFqMkM40w9z) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/netutil" ) func main() { type TodoQuery struct { Id int `json:"id"` UserId int `json:"userId"` Name string `json:"name,omitempty"` Status string } item := TodoQuery{ Id: 1, UserId: 123, Name: "test", Status: "completed", } queryValues := netutil.StructToUrlValues(item) fmt.Println(todoValues.Get("id")) fmt.Println(todoValues.Get("userId")) fmt.Println(todoValues.Get("name")) fmt.Println(todoValues.Get("status")) // Output: // 1 // 123 // test // } ``` ### HttpGet

发送http get请求。

> ⚠️ 本函数已弃用,使用`SendRequest`代替。 函数签名: ```go // params[0] http请求header,类型必须是http.Header或者map[string]string // params[1] http查询字符串,类型必须是url.Values或者map[string]string // params[2] post请求体,类型必须是[]byte // params[3] http client,类型必须是http.Client func HttpGet(url string, params ...any) (*http.Response, error) ``` 示例: ```go package main import ( "fmt" "io/ioutil" "log" "github.com/duke-git/lancet/v2/netutil" ) func main() { url := "https://jsonplaceholder.typicode.com/todos/1" header := map[string]string{ "Content-Type": "application/json", } resp, err := netutil.HttpGet(url, header) if err != nil { log.Fatal(err) } body, _ := ioutil.ReadAll(resp.Body) fmt.Println(body) } ``` ### HttpPost

发送http post请求。

> ⚠️ 本函数已弃用,使用`SendRequest`代替。 函数签名: ```go // params[0] http请求header,类型必须是http.Header或者map[string]string // params[1] http查询字符串,类型必须是url.Values或者map[string]string // params[2] post请求体,类型必须是[]byte // params[3] http client,类型必须是http.Client func HttpPost(url string, params ...any) (*http.Response, error) ``` 示例: ```go package main import ( "encoding/json" "fmt" "io/ioutil" "log" "github.com/duke-git/lancet/v2/netutil" ) func main() { url := "https://jsonplaceholder.typicode.com/todos" header := map[string]string{ "Content-Type": "application/x-www-form-urlencoded", } postData := url.Values{} postData.Add("userId", "1") postData.Add("title", "TestToDo") resp, err := netutil.HttpPost(apiUrl, header, nil, postData) if err != nil { log.Fatal(err) } body, _ := ioutil.ReadAll(resp.Body) fmt.Println(body) } ``` ### HttpPut

发送http put请求。

> ⚠️ 本函数已弃用,使用`SendRequest`代替。 函数签名: ```go // params[0] http请求header,类型必须是http.Header或者map[string]string // params[1] http查询字符串,类型必须是url.Values或者map[string]string // params[2] post请求体,类型必须是[]byte // params[3] http client,类型必须是http.Client func HttpPut(url string, params ...any) (*http.Response, error) ``` 示例: ```go package main import ( "encoding/json" "fmt" "io/ioutil" "log" "github.com/duke-git/lancet/v2/netutil" ) func main() { url := "https://jsonplaceholder.typicode.com/todos/1" header := map[string]string{ "Content-Type": "application/json", } type Todo struct { Id int `json:"id"` UserId int `json:"userId"` Title string `json:"title"` } todo := Todo{1, 1, "TestPutToDo"} bodyParams, _ := json.Marshal(todo) resp, err := netutil.HttpPut(url, header, nil, bodyParams) if err != nil { log.Fatal(err) } body, _ := ioutil.ReadAll(resp.Body) fmt.Println(body) } ``` ### HttpDelete

发送http delete请求。

> ⚠️ 本函数已弃用,使用`SendRequest`代替。 函数签名: ```go // params[0] http请求header,类型必须是http.Header或者map[string]string // params[1] http查询字符串,类型必须是url.Values或者map[string]string // params[2] post请求体,类型必须是[]byte // params[3] http client,类型必须是http.Client func HttpDelete(url string, params ...any) (*http.Response, error) ``` 示例: ```go package main import ( "encoding/json" "fmt" "io/ioutil" "log" "github.com/duke-git/lancet/v2/netutil" ) func main() { url := "https://jsonplaceholder.typicode.com/todos/1" resp, err := netutil.HttpDelete(url) if err != nil { log.Fatal(err) } body, _ := ioutil.ReadAll(resp.Body) fmt.Println(body) } ``` ### HttpPatch

发送http patch请求。

> ⚠️ 本函数已弃用,使用`SendRequest`代替。 函数签名: ```go // params[0] http请求header,类型必须是http.Header或者map[string]string // params[1] http查询字符串,类型必须是url.Values或者map[string]string // params[2] post请求体,类型必须是[]byte // params[3] http client,类型必须是http.Client func HttpPatch(url string, params ...any) (*http.Response, error) ``` 示例: ```go package main import ( "encoding/json" "fmt" "io/ioutil" "log" "github.com/duke-git/lancet/v2/netutil" ) func main() { url := "https://jsonplaceholder.typicode.com/todos/1" header := map[string]string{ "Content-Type": "application/json", } type Todo struct { Id int `json:"id"` UserId int `json:"userId"` Title string `json:"title"` } todo := Todo{1, 1, "TestPatchToDo"} bodyParams, _ := json.Marshal(todo) resp, err := netutil.HttpPatch(url, header, nil, bodyParams) if err != nil { log.Fatal(err) } body, _ := ioutil.ReadAll(resp.Body) fmt.Println(body) } ``` ### ParseHttpResponse

将http请求响应解码成特定struct值

函数签名: ```go func ParseHttpResponse(resp *http.Response, obj any) error ``` 示例: ```go package main import ( "encoding/json" "fmt" "io/ioutil" "log" "github.com/duke-git/lancet/v2/netutil" ) func main() { url := "https://jsonplaceholder.typicode.com/todos/1" header := map[string]string{ "Content-Type": "application/json", } resp, err := netutil.HttpGet(url, header) if err != nil { log.Fatal(err) } type Todo struct { Id int `json:"id"` UserId int `json:"userId"` Title string `json:"title"` Completed bool `json:"completed"` } toDoResp := &Todo{} err = netutil.ParseHttpResponse(resp, toDoResp) if err != nil { log.Fatal(err) } fmt.Println(toDoResp) } ``` ### DownloadFile

从指定的server地址下载文件。

函数签名: ```go func DownloadFile(filepath string, url string) error ``` 示例: ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/netutil" ) func main() { err := netutil.DownloadFile("./lancet_logo.jpg", "https://picx.zhimg.com/v2-fc82a4199749de9cfb71e32e54f489d3_720w.jpg?source=172ae18b") fmt.Println(err) } ``` ### UploadFile

将文件上传指定的server地址。

函数签名: ```go func UploadFile(filepath string, server string) (bool, error) ``` 示例: ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/netutil" ) func main() { ok, err := netutil.UploadFile("./a.jpg", "http://www.xxx.com/bucket/test") fmt.Println(ok) fmt.Println(err) } ``` ### IsPingConnected

检查能否ping通主机。

函数签名: ```go func IsPingConnected(host string) bool ``` 示例:[运行](https://go.dev/play/p/q8OzTijsA87) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/netutil" ) func main() { result1 := netutil.IsPingConnected("www.baidu.com") result2 := netutil.IsPingConnected("www.!@#&&&.com") fmt.Println(result1) fmt.Println(result2) // Output: // true // false } ``` ### IsTelnetConnected

检查能否telnet到主机。

函数签名: ```go func IsTelnetConnected(host string, port string) bool ``` 示例:[运行](https://go.dev/play/p/yiLCGtQv_ZG) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/netutil" ) func main() { result1 := netutil.IsTelnetConnected("www.baidu.com", "80") result2 := netutil.IsTelnetConnected("www.baidu.com", "123") fmt.Println(result1) fmt.Println(result2) // Output: // true // false } ``` ### BuildUrl

创建url字符串。

函数签名: ```go func BuildUrl(scheme, host, path string, query map[string][]string) (string, error) ``` 示例:[运行](todo) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/netutil" ) func main() { urlStr, err := netutil.BuildUrl( "https", "example.com", "query", map[string][]string{ "a": {"foo", "bar"}, "b": {"baz"}, }, ) fmt.Println(urlStr) fmt.Println(err) // Output: // https://example.com/query?a=foo&a=bar&b=baz // } ``` ### AddQueryParams

向url添加查询参数。

函数签名: ```go func AddQueryParams(urlStr string, params map[string][]string) (string, error) ``` 示例:[运行](todo) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/netutil" ) func main() { urlStr, err := netutil.BuildUrl( "https", "example.com", "query", map[string][]string{ "a": {"foo", "bar"}, "b": {"baz"}, }, ) fmt.Println(urlStr) fmt.Println(err) // Output: // https://example.com/query?a=foo&a=bar&b=baz // } ```