广告
返回顶部
首页 > 资讯 > 服务器 >Golang如何实现简单http服务器
  • 501
分享到

Golang如何实现简单http服务器

2023-07-05 14:07:15 501人浏览 八月长安
摘要

这篇文章主要介绍“golang如何实现简单Http服务器”,在日常操作中,相信很多人在Golang如何实现简单http服务器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang如何实现简单http服务器

这篇文章主要介绍“golang如何实现简单Http服务器”,在日常操作中,相信很多人在Golang如何实现简单http服务器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang如何实现简单http服务器”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一、基本描述

完成一个http请求的处理和响应,主要有以下几个步骤:

  • 监听端口

  • 建立连接

  • 解析http请求

  • 处理请求

  • 返回http响应

完成上面几个步骤,便能够实现一个简单的http服务器,完成对基本的http请求的处理

二 、具体方法

2.1 连接的建立

go中net包下有提供Listen和Accept两个方法,可以完成连接的建立,可以简单看下示例:

func main() {   // 对8080端口进行监听   l, _ := net.Listen("tcp", ":8080")   // 获取和端口8080完成三次握手的tcp连接   conn, _ := l.Accept()   // 此时便能够使用该连接和客户端进行通信   data := make([]byte, 4096)   // 可以从conn读取数据缓冲区当中   conn.Read(data)   // 将缓冲区的数据打印处理   print(string(data))}

可以运行这段代码,然后在浏览器对本地8080端口发送请求,该程序能够读取到浏览器发送过来的http请求体数据。

当通过Accept方法获取到连接后,能够使用该连接和客户端进行通信,该连接实现了net.Conn接口,具体接口的定义如下:

type Conn interface {   // Read reads data from the connection.   // Read can be made to time out and return an error after a fixed   // time limit; see SetDeadline and SetReadDeadline.   Read(b []byte) (n int, err error)   // Write writes data to the connection.   // Write can be made to time out and return an error after a fixed   // time limit; see SetDeadline and SetWriteDeadline.   Write(b []byte) (n int, err error)   // Close closes the connection.   // Any blocked Read or Write operations will be unblocked and return errors.   Close() error}

能够通过调用Read方法从客户端读取数据,使用Write方法往客户端返回数据。

2.2 http请求解析

当和客户端建立连接后,同时也能够读取到客户端发送过来的请求,此时要处理http请求的话,此时是需要解析出http请求体的,然后才能对http请求进行处理。接下来我们看一下一个http请求例子:

GET /ping HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platfORM: "MacOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWEBKit/537.36 (Khtml, like Gecko) Chrome/107.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
\r\n(空行)
hello world

接下来对HTTP请求体来进行分析,第一行是请求行,包含请求的方法,请求URI,以及HTTP版本。下面这个例子中,请求方法是GET,请求URI是/ping,HTTP版本是1.1。

GET /ping HTTP/1.1

请求行到空行之间的内容便是请求头部,每一个头部字段都有其对应的作用,比如Connection首部字段,这里值为keep-alive,这里的作用是告诉服务器,这个连接要处理多个http请求,不要处理完一个http请求就把连接断开了。

而且一个http请求首部字段,是可以有多个对应的值的,多个值之间用逗号隔开。

Cache-Control: public, max-age=31536000

第三部分的内容为请求体,也就是空行之后直到整个http请求的结束。可以看下面例子,请求体的内容是hello world。实际上GET请求是不应该有请求体的内容的,此处是我手动加进去的,只是为了方便展示使用。

GET /ping HTTP/1.1
....(省略http请求体部分首部字段)
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
\r\n(空行)
hello world

当我们了解完http请求体的结构,接下来可以编写代码来解析http请求体。

我们定义一个Conn结构体,由Conn完成数据的读取和HTTP请求体的解析,Conn定义如下:

type Conn struct {   rwc     net.Conn   // bufio.Reader 提供了缓存的功能,以及一些函数,方便我们解析HTTP请求体   br      *bufio.Reader   bw      *bufio.Writer   // 是否已经写入响应头   wroteHaeder bool } func NewConn(rwc net.Conn) *Conn {   return &Conn{      rwc:     rwc,      br:      bufio.NewReader(rwc),      bw:      bufio.NewWriter(rwc),   }}

同时解析出来的HTTP请求,也需要有个结构体来存储这部分数据,Request定义如下,这里暂时只支持GET请求,所以并没有保存请求体的内容

type Request struct {   // 存储请求方法,上面例子便是GET    method string   // 用于存储请求的uri   uri    string   // 用于存储http版本   proto  string   // http首部字段   Header map[string]string}

接下来由Conn完成HTTP请求体的解析,然后将解析的结果存储到Request对象当中。只需要根据HTTP请求体结构来进行解析即可,具体逻辑如下:

func (c *Conn) readRequest() (*Request, error) {   req := NewRequest()   // 现在只支持Get请求,读取第一行内容   // GET /ping HTTP1.1   line, err := c.br.ReadBytes('\n')   if err != nil {      return req, err   }   var f []string   // 按空格来进行分割,将请求行分割为三部分   if f = strings.Split(string(line), " "); len(f) != 3 {      return req, errors.New("http Header error")   }   // 获取到GET, /ping, HTTP/1.1   req.method, req.url, req.proto = f[0], f[1], f[2]   // 解析请求体首部字段   for {         line, err = c.br.ReadBytes('\n')      if err != nil {         return nil, err      }      // 当读取到空行时,说明已经首部字段已经读取完了      if len(strings.TrimSpace(string(line))) == 0 {         break      }      //举例,读取connection: keep-alive,获取第一个空格的下标      i := bytes.IndexByte(line, ' ')      if i == -1 {         return nil, errors.New("header is error")      }      // 此时获取到请求首部key,为connection      key := string(line[:i-1])      // 读取到对应的值,这里读取到keep-alive      value := strings.TrimSpace(string(line[i:]))      // 简单读取头部字段即可      req.Header[key] = value   }}

2.3 http请求处理

此时已经获取到HTTP请求了,之后需要对HTTP请求来进行处理,这里可以先简单进行处理,根据不同的请求执行不同的处理逻辑:

func main() {   // 对8080端口进行监听   l, _ := net.Listen("tcp", ":8080")   // 获取和端口8080完成三次握手的tcp连接   conn, _ := l.Accept()   // 获取到conn连接   c := NewConn(conn, handler)   // 读取到请求体   req, _ := c.readRequest()   if request.uri == "/hello" {     ....   }else{     ....    } }

2.4 http请求响应

当http请求处理完成之后,需要将返回一个处理结果返回给客户端,有时候还需要返回一些数据给客户端,这里返回的数据需要符合HTTP响应体的结构,接下来我们看看HTTP响应体的结构

HTTP/1.1 200 OK
Server: CloudWAF
Date: Sun, 04 Dec 2022 02:29:27 GMT
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Content-Language: zh-CN
Strict-Transport-Security: max-age= 31536000
Content-Encoding: gzip
\r\n(空行)
xxxx响应数据

可以看到,HTTP响应体和请求体结构类似,当需要返回数据给客户端时,需要按照HTTP协议定义好的响应体结构来进行返回,这样客户端才能够正确解析。

为了方便使用,构造HTTP响应体结构这部分逻辑应该由Conn对象来承载,由Conn对象提供一个Write方法,当需要返回数据时,只需要调用Write方法写入要返回的数据即可,不需要去操心去构造HTTP响应体的内容,Writer方法具体逻辑如下:

const (   StatusOK = 200)var statusText = map[int]string{   StatusOK:                   "OK",}// 返回响应行// 构造响应行 HTTP/1.1 200 OKfunc (c *Conn) writeHeader(status int) error {   if c.wroteHeader {      return errors.New("code has been set")   }   c.wroteHeader = true   var proto string   //GET /hello HTTP/1.1   proto = "HTTP/1.1"   // 获取文本描述,这里为OK   text, ok := statusText[status]   if !ok {      text = "status code " + strconv.Itoa(status)   }   // 写入数据 HTTP1.1 200 OK\r\n   c.bw.WriteString(proto + " " + strconv.Itoa(status) + " " + text + "\r\n")   // 写入空行   c.bw.Write("\r\n")   return nil}// 写入响应数据func (c *Conn) WriteData(data []byte) error {   // 还没写入请求头    if !c.wroteHeader {       //默认状态码是200 OK       c.writeHeader(StatusOK)   }   c.bw.Write(data)   return nil}

三、完整示例

func main() {   // 对8080端口进行监听   l, _ := net.Listen("tcp", ":8080")   // 获取和端口8080完成三次握手的tcp连接   conn, _ := l.Accept()   // 获取到conn连接   c := NewConn(conn)   // 读取到请求体   req, _ := c.readRequest()   if request.uri == "hello" {      c.WriteData("hello")   }else{      c.WriteData("hello world")   }   // 在最后,需要将缓冲区的数据进行清空   c.bw.Flush()   // 因为响应没有设置content-length,所以只有连接断开后,   // 浏览器才知道数据读取完成了,此处需要断开连接   c.rwc.Close() }

到此,关于“Golang如何实现简单http服务器”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: Golang如何实现简单http服务器

本文链接: https://www.lsjlt.com/news/352233.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Golang如何实现简单http服务器
    这篇文章主要介绍“Golang如何实现简单http服务器”,在日常操作中,相信很多人在Golang如何实现简单http服务器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang如何实现简单http服务器...
    99+
    2023-07-05
  • Golang实现简单http服务器的示例详解
    目录一、基本描述二 、具体方法2.1 连接的建立2.2 http请求解析2.3 http请求处理2.4 http请求响应三、完整示例一、基本描述 完成一个http请求的处理和响应,主...
    99+
    2023-03-20
    Golang实现http服务器 Golang http服务器 Golang 服务器
  • Golang中实现简单的Http Middleware
    本文主要针对Golang的内置库 net/http 做了简单的扩展,通过添加中间件的形式实现了管道(Pipeline)模式,这样的好处是各模块之间是低耦合的,符合单一职责原则,可以很...
    99+
    2022-11-12
  • Python实现简单的HTTP服务器(支
    python内置模块 SimpleHTTPServer  (支持下载功能) 在对应的工作目录下,运行命令python -m SimpleHTTPServer 即可把当前目录下以共享服务的形式共享出去。 外部访问可通过访问:http:/...
    99+
    2023-01-31
    简单 服务器 Python
  • 基于python的简单HTTP服务器实现
    HTTP协议 请求报文 请求头部字段解析 响应报文 响应头部字段解析 响应状态码 HTTP服务器实现 http协议大概是我们接触的最多的协议了,每打开一个网页,浏览器和服务器之间,使用的就是HTTP协议。...
    99+
    2023-01-31
    简单 服务器 python
  • Golang简单实现http的server端和client端
    介绍 HTTPS (Secure Hypertext Transfer Protocol)安全超文本传输协议,是一个安全通信通道,它基于HTTP开发用于在客户计算机和服务器之间交换...
    99+
    2022-11-12
  • golang DNS服务器的简单实现操作
    简单的DNS服务器 提供一个简单的可以查询域名和反向查询的DNS服务器。 dig命令主要用来从 DNS 域名服务器查询主机地址信息。 查找www.baidu.com的ip (A记录)...
    99+
    2022-11-12
  • 简单http和https服务器pytho
    欢迎加入python学习交流群 667279387 工作经常要用到测试http和https协议,这里写了两个简单的脚本实现简单的http服务器和https服务器。 http服务器代码 import sys import Base...
    99+
    2023-01-31
    简单 服务器 https
  • Python探索之实现一个简单的HTTP服务器
    Python标准库中的BaseHTTPServer模块实现了一个基础的HTTP服务器基类和HTTP请求处理类。这在文章python探索之BaseHTTPServer-实现Web服务器介绍中进行了相关的介绍。...
    99+
    2022-06-05
    简单 服务器 Python
  • 如何使用Golang实现简单的端口转发服务
    Golang(又称为Go)是由Google开发的一种开源编程语言。Golang具有高效、简洁、类C语言等特点,因此被广泛应用于网络编程。在网络编程中,端口转发是一个重要的技术。端口转发可以使一个计算机上的应用程序(例如Web服务器)能够访问...
    99+
    2023-05-14
  • 如何使用golang中的net/http/httputil.NewSingleHostReverseProxy实现简单的反向代理
    如何使用golang中的net/http/httputil.NewSingleHostReverseProxy实现简单的反向代理一、引言在现代互联网应用中,反向代理是一个非常重要的组件。它能够实现负载均衡,提高应用程序的可扩展性和可靠性。g...
    99+
    2023-11-18
    Golang 反向代理 httputil
  • 怎么在Golang中实现一个简单的Http中间件
    本篇内容主要讲解“怎么在Golang中实现一个简单的Http中间件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么在Golang中实现一个简单的Http中间件”吧!本文主要针对Golang的内...
    99+
    2023-06-20
  • Golang如何搭建HTTP服务器
    这篇文章主要讲解了“Golang如何搭建HTTP服务器”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Golang如何搭建HTTP服务器”吧!一. 安装Golang在开始之前,我们需要先安装好...
    99+
    2023-07-06
  • NodeJS创建最简单的HTTP服务器
    ☆ 引子 var http = require('http'); http.createServer(function(request, response){ response.writeHead...
    99+
    2022-06-04
    最简单 服务器 NodeJS
  • Qt实现简单TCP服务器
    本文实例为大家分享了Qt学习记录之简单的TCP服务器,供大家参考,具体内容如下 简单的多连接TCP服务器​ 本节我们使用Qt来编写一个简单的多连接TCP服务器程序,涉及到的功能有监听...
    99+
    2022-11-13
  • Python简单实现Web服务器
    import socket import re import gevent from gevent import monkey monkey.patch_all()# 识别等待时间,让协程切换 def client_handler(c...
    99+
    2023-01-31
    简单 服务器 Python
  • Python 实现简单 Web 服务器
    最近有个需求,就是要创建一个简到要多简单就有多简单的web服务器,目的就是需要一个后台进程用来接收请求然后处理并返回结果,因此就想到了使用python来实现。 首先创建一个myapp.py文件,其中定义了一个方法,所有的请求都会...
    99+
    2023-01-31
    简单 服务器 Python
  • 搭建简单的nodejs http服务器详解
    搭建简单的nodejs服务器 通过一些简单配置我们就可以搭建一台基于nodejs的http服务器 通过switch配置url路由的方法 // 这是一个简单的Node HTTP服务器,能处理当前目录的文件...
    99+
    2022-06-04
    详解 简单 服务器
  • 在 Golang 中实现一个简单的Http中间件过程详解
    本文主要针对Golang的内置库 net/http 做了简单的扩展,通过添加中间件的形式实现了管道(Pipeline)模式,这样的好处是各模块之间是低耦合的,符合单一职责原则,可以很...
    99+
    2022-11-12
  • 如何用Java编写你自己的简单HTTP服务器
    如何用Java编写你自己的简单HTTP服务器,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。HTTP是个大协议,完整功能的HTTP服务器必须响应资源请求,将URL转换为本地系...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作