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

如何在Go中制作HTTP服务器

引言

许多开发人员至少会花一些时间创建服务器,以便在互联网上分发内容。HTTP (Hypertext Transfer Protocol,超文本传输协议)提供了大部分这些内容,无论是请求一张猫的图片还是请求加载你正在阅读的教程。Go标准库为创建HTTP服务器以提供web内容或向这些服务器发出HTTP请求提供内置支持。

在本教程中,您将使用Go的标准库创建一个HTTP服务器,然后扩展服务器以从请求的查询字符串、请求体和表单数据中读取数据。你还需要更新程序,用自己的HTTP头和状态码响应请求。

设置项目

在Go中,标准库中的net/http包提供了大多数HTTP功能,而其余的网络通信由net包提供。net/http包不仅包含发出HTTP请求的能力,还提供了一个HTTP服务器,您可以使用它来处理这些请求。

在本节中,您将创建一个程序,它使用’ HTTP . listenandserve '函数来启动一个HTTP服务器,以响应请求路径//hello。然后,扩展该程序,在同一个程序中运行多个HTTP服务器。

不过,在编写代码之前,需要先创建程序的目录。许多开发人员将他们的项目放在一个目录中,以保持项目的组织。在本教程中,你将使用一个名为projects的目录。

首先,创建projects目录并导航到它:

mkdir projects
cd projects

接下来,创建项目目录并导航到该目录。在这种情况下,使用httpserver目录:

mkdir httpserver
cd httpserver

现在你已经创建了你的程序目录,并且你在httpserver目录下,你可以开始实现你的HTTP服务器了。

监听请求并提供响应

一个Go HTTP服务器包括两个主要组件:侦听来自HTTP客户端的请求的服务器和一个或多个将响应这些请求的请求处理程序。在本节中,你将从使用http.HandleFunc函数来告诉服务器调用哪个函数来处理对服务器的请求开始。然后,你将使用http.ListenAndServe函数来启动服务器,并告诉它监听新的HTTP请求,然后使用你设置的处理程序函数来处理它们。

现在,在你创建的httpserver目录中,使用nano或者你最喜欢的编辑器,打开main.go文件:

nano main.go

main.go文件中,你将创建两个函数,getRootgetHello,作为你的处理函数。然后,你将创建一个main函数,并使用http.HandleFunc函数来设置你的请求处理程序,方法是将/路径传递给getRoot函数,将/hello路径传递给getHello函数。一旦你设置了你的处理程序,调用http.ListenAndServe函数来启动服务器并监听请求。

将以下代码添加到该文件中,启动程序并设置处理程序:

main.go

package mainimport ("errors""fmt""io""net/http""os"
)func getRoot(w http.ResponseWriter, r *http.Request) {fmt.Printf("got / request\n")io.WriteString(w, "This is my website!\n")
}
func getHello(w http.ResponseWriter, r *http.Request) {fmt.Printf("got /hello request\n")io.WriteString(w, "Hello, HTTP!\n")
}

在这第一段代码中,你为Go程序设置了packageimport程序所需的包,并创建了两个函数:getRoot函数和getHello函数。这两个函数都有相同的函数签名,它们接受相同的参数:http.ResponseWriter值和*http.Request值。这个函数签名用于HTTP处理程序函数,定义为’ http.HandlerFunc '。当向服务器发出请求时,它使用正在发出的请求的信息设置这两个值,然后使用这些值调用处理程序函数。

http.HandlerFunc中,http.ResponseWriter值(在您的处理程序中名为w)用于控制将响应信息写回发出请求的客户端,例如响应体或状态码。然后,*http.Request值(在处理程序中名为r)用于获取进入服务器的请求的信息,例如在POST请求情况下发送的请求体或有关发出请求的客户端的信息。

现在,在你的两个HTTP处理程序中,你使用fmt.Printf来打印处理程序函数的请求,然后使用http.ResponseWriter向响应体发送一些文本。http.ResponseWriter是一个io.Writer,这意味着你可以使用任何能够写入该接口的东西来写入响应主体。在本例中,你使用io.WriteString函数将响应写入body。

现在,通过启动main函数来继续创建程序:

main.go

...
func main() {http.HandleFunc("/", getRoot)http.HandleFunc("/hello", getHello)err := http.ListenAndServe(":3333", nil)
...

main函数中,你有两次对http.HandleFunc函数的调用。对该函数的每次调用都会为默认的服务器多路复用器中的特定请求路径设置一个处理程序函数。服务器多路复用器是一个http.Handler,它能够查看请求路径并调用与该路径相关联的给定处理程序函数。所以,在你的程序中,你告诉默认的服务器多路复用器,当有人请求/路径时调用getRoot函数,当有人请求/hello路径时调用getHello函数。

一旦处理程序设置好了,你就可以调用http.ListenAndServe函数,它会告诉全局HTTP服务器使用可选的http.Handler在特定端口上监听传入的请求。在你的程序中,你告诉服务器监听":3333"。通过冒号前不指定IP地址,服务器将监听与计算机关联的每个IP地址,并且监听端口为3333。[网络端口](https://en.wikipedia.org/wiki/Port_(computer_networking),如这里的’ 3333 ',是一台计算机同时有许多程序相互通信的一种方式。每个程序都使用自己的端口,因此当客户端连接到特定的端口时,计算机就知道要把它发送到哪个程序。如果你只想允许连接到localhost,即IP地址为127.0.0.1的主机名,你可以改为127.0.0.1:3333

你的http.ListenAndServe函数也为http.Handler参数传递了一个nil值。这告诉ListenAndServe函数,你想使用默认的服务器多路复用器,而不是你设置的那个。

ListenAndServe是一个阻塞调用,这意味着你的程序在ListenAndServe结束运行之前不会继续运行。然而,ListenAndServe在你的程序结束运行或者HTTP服务器被告知关闭之前不会结束运行。即使ListenAndServe阻塞了,而且你的程序没有包含关闭服务器的方法,但包含错误处理仍然很重要,因为调用ListenAndServe可能会失败。因此,将错误处理添加到main函数的ListenAndServe中,如下所示:

main.go

...func main() {...err := http.ListenAndServe(":3333", nil)if errors.Is(err, http.ErrServerClosed) {fmt.Printf("server closed\n")} else if err != nil {fmt.Printf("error starting server: %s\n", err)os.Exit(1)<^>}
}

你要检查的第一个错误是’ http.ErrServerClosed ',它会在服务器被告知关闭或关闭时返回。这通常是一个意料之中的错误,因为你需要自己关闭服务器,但它也可以用来在输出中显示服务器停止的原因。在第二个错误检查中,检查是否有其他错误。如果发生这种情况,它会将错误打印到屏幕上,然后使用os.Exit函数退出程序,错误代码为1

在运行程序时,你可能会看到的一个错误是address already in use错误。当ListenAndServe无法监听你提供的地址或端口时,这个错误可能会返回,因为另一个程序已经在使用它。有时,如果端口是常用的,而你计算机上的另一个程序正在使用它,就会发生这种情况,但如果你多次运行自己程序的多个副本,也会发生这种情况。如果你在学习本教程时看到这个错误,请确保在再次运行程序之前已经停止了上一步的程序。

**注意:**如果你看到address already in use错误,并且你没有运行你的程序的另一个副本,这可能意味着其他程序正在使用它。如果发生这种情况,无论你在哪里看到本教程中提到的3333,将其更改为高于1024且低于65535的另一个数字,例如3334,然后重试。如果仍然看到错误,你可能需要继续寻找没有被使用的端口。一旦你找到一个可以工作的端口,就使用它来执行本教程中的所有命令。

现在你的代码已经准备好了,保存你的main.go文件并使用go run运行你的程序。与您可能编写的其他Go程序不同,此程序不会立即自己退出。运行程序后,继续执行下面的命令:

go run main.go

由于程序仍在终端中运行,因此需要打开第二个终端与服务器交互。当你看到命令或输出与下面的命令相同的颜色时,意味着要在第二个终端中运行它。

在第二个终端中,使用curl程序向HTTP服务器发出HTTP请求。curl是一个默认安装在许多系统上的实用工具,它可以向各种类型的服务器发出请求。在本教程中,你将使用它来发起HTTP请求。你的服务器在你计算机的3333端口上监听连接,所以你需要在同一个端口上向localhost发起请求:

curl http://localhost:3333
OutputThis is my website!

在输出中,你会看到This is my website!,因为你访问了HTTP服务器上的/路径。

现在,在相同的终端中,向相同的主机和端口发出请求,但在curl命令的末尾添加/hello路径:

curl http://localhost:3333/hello
OutputHello, HTTP!

这次你会看到Hello, HTTP!返回getHello函数的响应。

如果回到运行HTTP服务器函数的终端,现在会看到服务器输出的两行内容。一个用于/请求,另一个用于/hello请求:

Outputgot / request
got /hello request

因为

相关文章:

如何在Go中制作HTTP服务器

引言 许多开发人员至少会花一些时间创建服务器,以便在互联网上分发内容。HTTP (Hypertext Transfer Protocol,超文本传输协议)提供了大部分这些内容,无论是请求一张猫的图片还是请求加载你正在阅读的教程。Go标准库为创建HTTP服务器以提供web内容或向这些服务器发出HTTP请求…...

Linux笔记---系统信息

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Linux学习 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 命令 1. uname - 显示系统信息 2. hostname - 显示或设置系统主机名 3. top - 显示系统资源使用情况 4. df - 显示磁盘空间使用情…...

最新版android stuido加上namespace

每个 Android 模块都有一个命名空间&#xff0c;此命名空间用作其生成的 命名空间由模块的 build.gradle 文件中的 namespace 属性定义&#xff0c;如以下代码段所示。namespace 最初会设为您在创建项目时选择的软件包名称。 Kotlin Groovy android {namespace "com.ex…...

Wireshark基础及捕获技巧

第一章&#xff1a;Wireshark基础及捕获技巧 1.1 Wireshark基础知识回顾 1.2 高级捕获技巧&#xff1a;过滤器和捕获选项 1.3 Wireshark与其他抓包工具的比较 第二章&#xff1a;网络协议分析 2.1 网络协议分析&#xff1a;TCP、UDP、ICMP等 2.2 高级协议分析&#xff1a;HTTP…...

Windows下Navicat15.0连接Oracle11g报ORA-28547解决

目录 背景 一、相关环境 1、操作系统 2、Navicat版本 3、ORACLE连接 4、默认连接 二、问题分析 1、默认dll配置 三、修改配置 1、下载匹配的client 2、替换相应目录 总结 背景 最近在项目中需要使用Oracle数据库&#xff0c;当前很多应用系统的数据都存储在MySQL或者Pos…...

21 Vue3中使用v-for遍历对象数组

概述 使用v-for遍历对象数组在真实的开发中也属于非常常见的用法&#xff0c;需要重点掌握。 因为目前流行的是前后端分离开发&#xff0c;在前后端分离开发中&#xff0c;最常需要处理的就是对象数组类型的数据了。 比如&#xff0c;将员工信息渲染到表格中。 这节课我们就…...

深入理解Java自定义异常与全局异常处理 @RestControllerAdvice

异常主要是包括编译时的异常和运行时的异常。编译时的异常可以通过捕获异常获取&#xff0c;运行时候的异常主要是通过代码规范&#xff0c;或者测试。 Spring Boot提供了两种异常处理方式来统一处理和维护异常信息。 第一种方式是使用RestControllerAdvice注解与ExceptionHand…...

h5页面跳转微信小程序(最简单的方法|URL Scheme)

文章目录 导文实现获取 URL Scheme加密 URL Scheme获取方式拼接参数 明文 URL Scheme获取方式 实际项目展示&#xff1a;频率限制注意事项开放范围示例代码包 导文 H5页面跳转微信小程序的需求是普遍存在的。由于微信小程序是一种只能在微信内部访问的应用程序&#xff0c;而H5…...

智能优化算法应用:基于非洲秃鹫算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于非洲秃鹫算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于非洲秃鹫算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.非洲秃鹫算法4.实验参数设定5.算法结果6.…...

持续集成交付CICD:Jenkins使用GitLab共享库实现前端项目镜像构建

目录 一、实验 1. GitLab修改项目文件与Harbor环境确认 2.Jenkins使用GitLab共享库实现前端项目镜像构建 3.优化CI流水线封装Harbor账户密码 4.Jenkins再次使用GitLab共享库实现前端项目镜像构建 一、实验 1. GitLab修改项目文件与Harbor环境确认 &#xff08;1&#xf…...

SQL server 数据库 SQL语句高级用法

1、表的高级查询 use student select * from stuinfo1 -- 使用 in 的子查询 select * from stuinfo where stu_age in ( select stu_age from stuinfo where cla_id 12345 ) select * from stuinfo where stu_age in ( 19 , 20 , 21 , 25 , 23 , 1…...

wavlink 路由器 多处前台RCE漏洞复现

0x01 产品简介 WAVLINK是中国睿因科技(WAVLINK)公司开发的一款路由器。 0x02 漏洞概述 WAVLINK路由器mesh.cgi、nightled.cgi、live-api.cgi等接口处存在命令执行漏洞,攻击者可通过该漏洞获取服务器权限。包含型号WN530HG4、WN531G3、WN572HG3、WN535G3、WN575A4等。 0x…...

互联网中的商品超卖问题及其解决方案:Java中Redis结合UUID的应用

前言 在设计商品下单和库存扣减&#xff0c;你一定遇到过这样的问题&#xff0c;库存扣减为0了&#xff0c;可是消费者还能下单&#xff0c;并将订单信息保存到了数据库里&#xff0c;针对商品超卖问题&#xff0c;作此篇以解决。 随着互联网商业的飞速发展&#xff0c;商品超…...

mysql:查看线程缓存中的线程数量

使用命令show global status like Threads_cached;可以查看线程缓存中的线程数量。 例如&#xff0c;查询线程缓存中的线程数量如下&#xff1a; 然后启动应用程序&#xff0c;使用连接&#xff0c;查询如下&#xff1a; 由查询结果可以看到&#xff0c;线程缓存中的线程数量…...

线性表,也是Java中数组的知识点!

线性表定义&#xff1a; 由n (n≥0)个数据特性相同的元素构成的有限序列称为线性表&#xff0c;(n0)的时候被称为空表。 线性表的顺序表示 线性表的顺序存储又被称为顺序表 优点 无需为表示表中元素之间的逻辑关系而增加额外的存储空间可以随意读取任意位置的元素 缺点 插入…...

java使用面向对象实现图书管理系统

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …...

2023 英特尔On技术创新大会直播 |我感受到的“芯”魅力

文章目录 每日一句正能量前言AI时代&#xff0c;云与PC结合为用户带来更好体验全新处理器&#xff0c;首次引入针对人工智能加速的NPU大模型时代&#xff0c;软硬结合带来更好训练成果后记 每日一句正能量 成长是一条必走的路路上我们伤痛在所难免。 前言 在2023年的英特尔On技…...

Atium Designer 23 全新功能-丝印制备,解决DFM问题

进行PCB设计时需要养成良好的设计习惯&#xff0c;才能保证后期的生产效果。例如整板上需要保证丝印跟阻焊的间距规则避免产生丝印重叠造成的PCB制造设计&#xff08;DFM&#xff09;问题。丝印重叠阻焊的影响有如下&#xff1a; 1&#xff09;PCB板后期打样&#xff0c;一般是…...

Nginx快速入门:安装目录结构详解及核心配置解读(二)

0. 引言 上节我们讲解了nginx的应用场景和安装&#xff0c;本节继续针对nginx的各个目录文件进行讲解&#xff0c;让大家更加深入的认识nginx。并通过一个实操案例&#xff0c;带大家来实际认知nginx的核心配置 1. nginx安装目录结构 首先nginx的默认安装目录为&#xff1a;…...

测试TensorFlow/PyTorch的GPU版本是否启用

文章目录 1. Pytorch测试代码2. TensorFlow测试代码 后续遇到好的会不断更新。。。 1. Pytorch测试代码 import torch def gpu_is_available():print(\nGPU details:)print(f gpu_is_available : , torch.cuda.is_available())print(f cuda_device_count : , t…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究

摘要&#xff1a;在消费市场竞争日益激烈的当下&#xff0c;传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序&#xff0c;探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式&#xff0c;分析沉浸式体验的优势与价值…...

qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001

qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类&#xff0c;直接把源文件拖进VS的项目里&#xff0c;然后VS卡住十秒&#xff0c;然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分&#xff0c;导致编译的时候找不到了。因…...