Go编写http server

        一般来说,理解 HTTP 构建的网络应用,只要关注客户端(clinet)和服务端(server),两个端的交互来自客户端的 request,以及服务端的response。所谓的http服务器,主要在于如何接受客户端的 request,并向服务端返回response。

        Http接收和响应来自客户端的HTTP请求,需要用到golang自带的net.http包,实现动态请求处理。Go语言内置的net/http包提供了HTTP客户端和服务端的实现。

        在接受的过程中路由(router)十分重要,路由url到函数的映射,而这里的路由目的就是为了找到处理器函数(handler),函数将对来自客户端request进行处理,同时构建response返回至服务器。

一、路由

路由就是url到函数的映射

route就是你访问一个页面的地址。router就是由一群地址组成的东西。

当访问/healthz路径时,会执行healthz函数

服务器端

       简单来说,对于服务器,当接收到客户端发来的HTTP请求,会根据请求的URL,来找到相应的映射函数,然后执行该函数,并将函数的返回值发送给客户端。

静态资源服务器:url映射函数可以理解为一个文件读取操作

动态资源服务器:url映射可以理解为从数据库读取操作,或是数据处理

客户端

路由的映射函数通常是进行一些DOM的显示和隐藏操作。

二、HTTP请求的接收与处理流程

1、客户端将请求发送到服务器(指定URL)。
2、服务器将请求指向到正确的处理器,然后由该处理器对请求进行处理。
3、处理器处理请求,执行必要的动作。
4、处理器将结果返回给客户端。

三、开始创建http server 

        在理解以上概念后,就要进入http server的创建了。创建httpserver有两个步骤,首先是注册路由,接下来就是其次就是实例化一个server对象,开始监听来自客户端request。

注册路由

通过这个包的http.HandleFunc函数,我们可一个注册一个请求处理器,该函数的第一个参数是请求路径的字符串,第二个参数即为处理请求的函数主体func(ResponseWriter, * Request) 类型的函数。

 http.HandleFunc("/", httpAccessFunc)

http.Handle和http.HandleFunc区分

Go 网络编程:使用 Handler 和 HandlerFunc - 简书

简单的httpserver

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/healthz", healthz)
    //handle定义请求访问该服务器里的/healthz路径,就有下面healthz去处理,healthz一般为健康检查
    err := http.ListenAndServe(":80", nil)
    if err != nil {
        log.Fatal(err)
        }
    }
//定义handle处理函数,只要该healthz被调用,就会写入ok
func healthz(w http.ResponseWriter, request *http.Request) {
    io.WriteString(w, "ok")
}

编写http server

要求:

1、接收客户端 request,并将 request 中带的 header 写入 response header

2、读取当前系统的环境变量中的 VERSION 配置,并写入 response header

3、Server 端记录访问日志包括客户端 IP,HTTP 返回码,输出到 server 端的标准输出

4、当访问 localhost/healthz 时,应返回 200

package main

import (
	"fmt"
	"log"
	"net"
	"net/http"
	"os"
	"strconv"
)

func main() {
	HttpServerStart(8080)
	log.Fatal(http.ListenAndServe("localhost:8000", nil))
}

func HttpServerStart(port int) {
	log.SetPrefix("Info:")                  //为每条日志文本前增加一个info:前缀
	log.SetFlags(log.Ldate | log.Llongfile) //可以获取当前设置的选项,Ldate:输出当地时区的日期;Llongfile:输出长文件名+行号

	http.HandleFunc("/", httpAccessFunc) //http.HandleFunc接收两个参数,一个是路由匹配的字符串,另外一个是 func(ResponseWriter, *Request) 类型的函数
	http.HandleFunc("healthz", healthzFunc)

	err := http.ListenAndServe(":"+strconv.Itoa(port), nil)
	if err != nil {
		log.Fatal(err) //输出日志后,调用os.Exit(1)退出程序
	}
}

func healthzFunc(w http.ResponseWriter, r *http.Request) {
	HealthzCode := "200"
	w.Write([]byte(HealthzCode))
}

func httpAccessFunc(w http.ResponseWriter, r *http.Request) {
	if len(r.Header) > 0 {
		for k, v := range r.Header {
			log.Printf("%s=%s", k, v[0])

			//1. request header写入response header
			w.Header().Set(k, v[0])
		}
	}

	log.Printf("\n\n\n")

	r.ParseForm() //解析所有请求数据,否则无法获取数据
	if len(r.Form) > 0 {
		for k, v := range r.Form {
			log.Printf("%s=%s", k, v[0])
		}
	}
	log.Printf("\n\n\n")

	os.Setenv("VERSION", "JDK version 1.11.0") //设置环境值的值

	//2. 获取环境变量"VERSION"
	name := os.Getenv("VERSION")
	log.Printf("VERSION Env: ", name)

	log.Printf("\n\n\n")

	//3.获取Client IP,并且打印出来
	ip, _, err := net.SplitHostPort(r.RemoteAddr)
	if err != nil {
		fmt.Println("err:", err)
	}

	if net.ParseIP(ip) != nil {
		fmt.Println("ip ===>>%s\n", ip)
		log.Println(ip)
	}

	fmt.Println("http Status Code ===>>%s\n", http.StatusOK)
	log.Println(http.StatusOK)

	//response响应
	w.WriteHeader(http.StatusOK)

	w.Write([]byte("Server Access,Success!"))
}

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Golang编写一个简单的HTTP服务器可以有多种方式。下面是两种常见的实现方式: 第一种方式是使用`http.HandleFunc`函数和一个处理函数来实现。代码如下所示: ```go package main import ( "fmt" "net/http" ) func indexHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hello world") } func main() { http.HandleFunc("/", indexHandler) http.ListenAndServe(":8000", nil) } ``` 在这个例子中,我们定义了一个`indexHandler`函数来处理根路径的请求。当有请求到达时,`indexHandler`函数会将"hello world"作为响应写入到`http.ResponseWriter`中。 第二种方式是使用自定义的处理器类型和`http.Handle`函数来实现。代码如下所示: ```go package main import ( "fmt" "net/http" ) type indexHandler struct { content string } func (ih *indexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ih.content) } func main() { http.Handle("/", &indexHandler{content: "hello world!"}) http.ListenAndServe(":8001", nil) } ``` 在这个例子中,我们定义了一个`indexHandler`类型,并实现了`ServeHTTP`方法。当有请求到达时,`ServeHTTP`方法会将`indexHandler`的`content`字段作为响应写入到`http.ResponseWriter`中。 无论是哪种方式,我们都需要使用`http.ListenAndServe`函数来启动服务器。这个函数会监听指定的地址,并将请求交给指定的处理器来处理。 希望这个例子能帮助你理解如何使用Golang编写一个简单的HTTP服务器。 #### 引用[.reference_title] - *1* *2* *3* [golang http Server介绍](https://blog.csdn.net/zrg3699/article/details/122280399)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值