想写个web服务器开发语言,用Go语言实现,需要有哪些前提知识

15359人阅读
go语言入门(3)
概述 上一篇讲了 ,接下来讲一下Go语言Web开发入门必修课:第一个Go语言Web程序——简单的Web服务器。与其它Web后端语言不同,Go语言需要自己编写Web服务器。有关本地环境的搭建与基础学习,请参考: Go语言Web应用:Web服务器代码Google在&上提供了一个将表单数据自动转换为图表的服务。不过,该服务很难交互, 因为你需要将数据作为查询放到URL中。此程序为一种数据格式提供了更好的的接口: 给定一小段文本,它将调用图表服务器来生成二维码(QR码),这是一种编码文本的点格矩阵。 该图像可被你的手机摄像头捕获,并解释为一个字符串,比如URL, 这样就免去了你在狭小的手机键盘上键入URL的麻烦。以下为完整的程序,随后有一段解释。package main
&html/template&
&net/http&
var addr = flag.String(&addr&, &:1718&, &http service address&) // Q=17, R=18
var templ = template.Must(template.New(&qr&).Parse(templateStr))
func main() {
flag.Parse()
http.Handle(&/&, http.HandlerFunc(QR))
err := http.ListenAndServe(*addr, nil)
if err != nil {
log.Fatal(&ListenAndServe:&, err)
func QR(w http.ResponseWriter, req *http.Request) {
templ.Execute(w, req.FormValue(&s&))
const templateStr = `
&title&QR Link Generator&/title&
&img src=&http://chart./chart?chs=300x300&cht=qr&choe=UTF-8&chl={{.}}& /&
&form action=&/& name=f method=&GET&&&input maxLength=1024 size=70
name=s value=&& title=&Text to QR Encode&&&input type=submit
value=&Show QR& name=qr&
`main&之前的代码应该比较容易理解。我们通过一个标志为服务器设置了默认端口。 模板变量&templ&正式有趣的地方。它构建的HTML模版将会被服务器执行并显示在页面中。 稍后我们将详细讨论。main&函数解析了参数标志并使用我们讨论过的机制将&QR&函数绑定到服务器的根路径。然后调用&http.ListenAndServe&启动服务器;它将在服务器运行时处于阻塞状态。QR&仅接受包含表单数据的请求,并为表单值&s&中的数据执行模板。模板包&html/template&非常强大;该程序只是浅尝辄止。 本质上,它通过在运行时将数据项中提取的元素(在这里是表单值)传给&templ.Execute&执行因而重写了HTML文本。 在模板文本(templateStr)中,双大括号界定的文本表示模板的动作。 从&{{if .}}&到&{{end}}&的代码段仅在当前数据项(这里是点&.)的值非空时才会执行。 也就是说,当字符串为空时,此部分模板段会被忽略。其中两段&{{.}}&表示要将数据显示在模板中 (即将查询字符串显示在Web页面上)。HTML模板包将自动对文本进行转义, 因此文本的显示是安全的。余下的模板字符串只是页面加载时将要显示的HTML。如果这段解释你无法理解,请参考&&获得更多有关模板包的解释。你终于如愿以偿了:以几行代码实现的,包含一些数据驱动的HTML文本的Web服务器。 Go语言强大到能让很多事情以短小精悍的方式解决。编译运行访问在Go的安装目录下的Src目录下创建一个目录,我的Go安装在D盘,所以我在D:\Go\src\目录下创建了一个“web1”文件夹,新建了一个“web1.go”文件,将上面的代码复制粘贴到文件中,保存。编译你可以通过在命令行窗口执行命令:go install web1&来完成编译,编译完成后会在&D:\Go\bin&目录下生成web1的exe。执行通过上面的方法编译后,双击运行即可。也可以在命令行下切换到文件所在的目录,例如:D:\Go\src\web1然后执行:go run web1.go结果如下图:点击允许访问。访问在浏览器中访问,查看效果,打开浏览器,输入:,结果如下图:在文本框中输入一个URL,如(http://blog.csdn.net/testcs_dn),点击Show QR,会生成一张二维码的图片扫一扫这张二维码看看吧小结与其它Web后端语言不同,Go语言需要自己编写Web服务器。这里只是编译运行一个简单的例子,看看效果找找感觉。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:8331218次
积分:62528
积分:62528
排名:第38名
原创:800篇
转载:223篇
译文:53篇
评论:1775条
文章:158篇
阅读:2253474
文章:33篇
阅读:214053
文章:16篇
阅读:178381
阅读:15946
文章:29篇
阅读:401629
文章:18篇
阅读:368938
文章:44篇
阅读:394228
(5)(56)(30)(17)(14)(18)(27)(16)(9)(23)(20)(17)(4)(16)(12)(17)(25)(34)(19)(15)(17)(15)(23)(12)(12)(14)(13)(14)(20)(58)(25)(31)(16)(33)(31)(20)(24)(23)(21)(20)(14)(36)(14)(14)(7)(5)(15)(3)(2)(9)(6)(7)(32)(3)(8)(7)(22)(2)(30)(4)
关注我的订阅号“微wx笑”Go语言实现简单的一个静态WEB服务器
- Go语言中文网 - Golang中文社区
<meta name="author" content="polaris ">
Go语言实现简单的一个静态WEB服务器
mickelfeng
· 1535 次点击 ·
开始浏览 & &
学习Go语言的一些感受,不一定准确。
假如发生战争,JAVA一般都是充当航母战斗群的角色。 一旦出动,就是护卫舰、巡洋舰、航母舰载机、预警机、电子战飞机、潜艇等等 浩浩荡荡,杀将过去。 (JVM,数十个JAR包,Tomcat中间件,SSH框架,各种配置文件...天生就是重量级的,专为大规模作战)
而GO语言更像F35战斗轰炸机 单枪匹马,悄无声息,投下炸弹然后走人。 专属轰炸机,空战也会一点点. 实在搞不定,就叫它大哥F22。 (GO是编译型语言,不需要依赖,不需要虚拟机,可以调用C代码并且它足够简单,却非常全面)
计划Go语言学习的知识点
1.搭建Http服务 2.连接数据库 3.本地IO 4.多线程 5.网络 6.调用本地命令 7.调用C语言代码
首先,搭建一个静态的服务器 我写程序喜欢使用HTML通过AJAX发送JSON请求到后端处理。
HttpServer.go
package main
&#34;flag&#34;
&#34;io/ioutil&#34;
&#34;log&#34;
&#34;net/http&#34;
&#34;os&#34;
&#34;strings&#34;
var realPath *string
func staticResource(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
request_type := path[strings.LastIndex(path, &#34;.&#34;):]
switch request_type {
case &#34;.css&#34;:
w.Header().Set(&#34;content-type&#34;, &#34;text/css&#34;)
case &#34;.js&#34;:
w.Header().Set(&#34;content-type&#34;, &#34;text/javascript&#34;)
fin, err := os.Open(*realPath + path)
defer fin.Close()
if err != nil {
log.Fatal(&#34;static resource:&#34;, err)
fd, _ := ioutil.ReadAll(fin)
w.Write(fd)
func main() {
realPath = flag.String(&#34;path&#34;, &#34;&#34;, &#34;static resource path&#34;)
flag.Parse()
http.HandleFunc(&#34;/&#34;, staticResource)
err := http.ListenAndServe(&#34;:8080&#34;, nil)
if err != nil {
log.Fatal(&#34;ListenAndServe:&#34;, err)
网上看到一个更BT的方法:
package main
&#34;net/http&#34;
func main() {
http.Handle(&#34;/&#34;, http.FileServer(http.Dir(&#34;/tmp/static/&#34;)))
http.ListenAndServe(&#34;:8080&#34;, nil)
将EasyUI前端框架解压到 /tmp/static 目录下:
在GOPATH下执行
go run HttpServer.go --path=/tmp/static
查看网页,一切正常。
这样Go语言以不到50行代码,编译之后不到7M的可执行文件,就实现了一个简易的静态服务器。
1535 次点击 &
请尽量让自己的回复能够对别人有帮助
支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
支持 @ 本站用户;支持表情(输入 : 提示),见
图片支持拖拽、截图粘贴等方式上传
记住登录状态
学习Go语言的一些感受,不一定准确。
假如发生战争,JAVA一般都是充当航母战斗群的角色。 一旦出动,就是护卫舰、巡洋舰、航母舰载机、预警机、电子战飞机、潜艇等等 浩浩荡荡,杀将过去。 (JVM,数十个JAR包,Tomcat中间件,SSH框架,各种配置文件...天生就是重量级的,专为大规模作战)
而GO语言更像F35战斗轰炸机 单枪匹马,悄无声息,投下炸弹然后走人。 专属轰炸机,空战也会一点点. 实在搞不定,就叫它大哥F22。 (GO是编译型语言,不需要依赖,不需要虚拟机,可以调用C代码并且它足够简单,却非常全面)
计划Go语言学习的知识点
1.搭建Http服务 2.连接数据库 3.本地IO 4.多线程 5.网络 6.调用本地命令 7.调用C语言代码
首先,搭建一个静态的服务器 我写程序喜欢使用HTML通过AJAX发送JSON请求到后端处理。
HttpServer.go
package main
&#34;flag&#34;
&#34;io/ioutil&#34;
&#34;log&#34;
&#34;net/http&#34;
&#34;os&#34;
&#34;strings&#34;
var realPath *string
func staticResource(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
request_type := path[strings.LastIndex(path, &#34;.&#34;):]
switch request_type {
case &#34;.css&#34;:
w.Header().Set(&#34;content-type&#34;, &#34;text/css&#34;)
case &#34;.js&#34;:
w.Header().Set(&#34;content-type&#34;, &#34;text/javascript&#34;)
fin, err := os.Open(*realPath + path)
defer fin.Close()
if err != nil {
log.Fatal(&#34;static resource:&#34;, err)
fd, _ := ioutil.ReadAll(fin)
w.Write(fd)
func main() {
realPath = flag.String(&#34;path&#34;, &#34;&#34;, &#34;static resource path&#34;)
flag.Parse()
http.HandleFunc(&#34;/&#34;, staticResource)
err := http.ListenAndServe(&#34;:8080&#34;, nil)
if err != nil {
log.Fatal(&#34;ListenAndServe:&#34;, err)
网上看到一个更BT的方法:
package main
&#34;net/http&#34;
func main() {
http.Handle(&#34;/&#34;, http.FileServer(http.Dir(&#34;/tmp/static/&#34;)))
http.ListenAndServe(&#34;:8080&#34;, nil)
将EasyUI前端框架解压到 /tmp/static 目录下:
在GOPATH下执行
go run HttpServer.go --path=/tmp/static
查看网页,一切正常。
这样Go语言以不到50行代码,编译之后不到7M的可执行文件,就实现了一个简易的静态服务器。
102 人在线
&最高记录 1364
&2012- Go语言中文网,中国 Golang 社区,致力于构建完善的 Golang 中文社区,Go语言爱好者的学习家园。
Powered by
&o&服务器由
赞助 &·&CDN 由
VERSION: V3.0.0&·&3.821121ms&·&为了更好的体验,本站推荐使用 Chrome 或 Firefox 浏览器
登录和大家一起探讨吧
记住登录状态
还不是会员想写个web服务器,用Go语言实现,需要有哪些前提知识呢? - 知乎92被浏览7626分享邀请回答301 条评论分享收藏感谢收起package main
import "net/http"
func HandlerIndex(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World!"))
func main() {
http.HandleFunc("/", HandlerIndex)
http.ListenAndServe(":8080", nil)
2. 如何处理 POST 请求, 访问 127.0.0.1:8080/postpackage main
"io/ioutil"
"net/http"
func HandlerPost(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
content, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(400)
w.Write([]byte(err.Error()))
w.WriteHeader(200)
w.Write(content)
func main() {
http.HandleFunc("/post", HandlerPost)
http.ListenAndServe("127.0.0.1:8080", nil)
3. 一个完整的, 线上运行的 http 服务器长啥样package main
"net/http"
type Handler struct {
mux map[string]func(http.ResponseWriter, *http.Request)
func NewHandler() *Handler {
Handler := &Handler{}
Handler.mux = make(map[string]func(http.ResponseWriter, *http.Request))
return Handler
func (Handler *Handler) Bind(pattern string, handler func(w http.ResponseWriter, r *http.Request)) {
Handler.mux[pattern] = handler
func (Handler *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
zero := time.Now()
defer func() {
duration := time.Since(zero)
log.Printf("%s [%.2f] %s \n", r.Method, duration.Seconds(), r.URL)
if h, ok := Handler.mux[r.URL.String()]; ok {
w.WriteHeader(404)
func HandlerGet(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("Hello World!"))
func main() {
Handler := NewHandler()
Handler.Bind("/get", HandlerGet)
server := http.Server{
"127.0.0.1:8080",
Handler: Handler,
server.ListenAndServe()
4. 你可能想监控服务器的性能 / qps查看标准库 expvar, pprof.所有代码均托管在 gist 上, 欢迎访问. 193 条评论分享收藏感谢收起查看更多回答在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
刚开始接触服务器端开发,使用的是model,controller模式做restful的web服务器。
想知道如何设计router与model?有个朋友跟我说把router与model写在一起,在初始化model的同时,对应model的router也能一起初始化好,不过没太理解。。。。。
而且虽说model种类可能有很多,但是会有一些增删改查的操作很类似,如何防止过多重复的代码,使用interface?
希望有经验的前辈可以指点一二
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
看看beego是怎么实现的
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
可以读一读
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
Revel 框架的也不错,可以看看
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
beego~~~~~~~~
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:15.2 一个简单的网页服务器
Http是一个比tcp更高级的协议,它描述了客户端浏览器如何与网页服务器进行通信。Go有自己的net/http包,我们来看看它。我们从一些简单的示例开始,
首先编写一个“Hello world!”:
我们引入了http包并启动了网页服务器,和15.1的net.Listen("tcp", "localhost:50000")函数的tcp服务器是类似的,使用http.ListenAndServe("localhost:8080", nil)函数,如果成功会返回空,否则会返回一个错误(可以指定localhost为其他地址,8080是指定的端口号)
http.URL描述了web服务器的地址,内含存放了url字符串的Path属性;http.Request描述了客户端请求,内含一个URL属性
如果req请求是一个POST类型的html表单,“var1”就是html表单中一个输入属性的名称,然后用户输入的值就可以通过GO代码:req.FormValue("var1")获取到(请看)。还有一种方法就是先执行request.ParseForm()然后再获取`request.Form[&var1&]的第一个返回参数,就像这样:
var1, found := request.Form["var1"]
第二个参数found就是true,如果var1并未出现在表单中,found就是false
表单属性实际上是一个map[string][]string类型。网页服务器返回了一个http.Response,它是通过http.ResponseWriter对象输出的,这个对象整合了HTTP服务器的返回结果;通过对它写入内容,我们就将数据发送给了HTTP客户端。
现在我们还需要编写网页服务器必须执行的程序,它是如何处理请求的呢。这是在http.HandleFunc函数中完成的,就是在这个例子中当根路径“/”(url地址是http://localhost:8080 )被请求的时候(或者这个服务器上的其他地址),HelloServer函数就被执行了。这个函数是http.HandlerFunc类型的,它们通常用使用Prehandler来命名,在前边加了一个Pref前缀。
http.HandleFunc注册了一个处理函数(这里是HelloServer)来处理对应/的请求。
/可以被替换为其他特定的url比如/create,/edit等等;你可以为每一个特定的url定义一个单独的处理函数。这个函数需要两个参数:第一个是ReponseWriter类型的w;第二个是请求req。程序向w写入了Hello和r.URL.Path[1:]组成的字符串后边的[1:]表示“创建一个从第一个字符到结尾的子切片”,用来丢弃掉路径开头的“/”,fmt.Fprintf()函数完成了本次写入(请看);另外一种写法是io.WriteString(w, "hello, world!\n")
总结:第一个参数是请求的路径,第二个参数是处理这个路径请求的函数的引用。
示例 15.6 :
package main
"net/http"
func HelloServer(w http.ResponseWriter, req *http.Request) {
fmt.Println("Inside HelloServer handler")
fmt.Fprintf(w, "Hello,"+req.URL.Path[1:])
func main() {
http.HandleFunc("/", HelloServer)
err := http.ListenAndServe("localhost:8080", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err.Error())
使用命令行启动程序,会打开一个命令窗口显示如下文字:
Starting Process E:/Go/GoBoek/code_examples/chapter_14/hello_world_webserver.exe
然后打开你的浏览器并输入url地址:http://localhost:8080/world,浏览器就会出现文字:Hello, world,网页服务器会响应你在:8080/后边输入的内容
使用fmt.Println在控制台打印状态,在每个handler被请求的时候,在他们内部打印日志会很有帮助
1)前两行(没有错误处理代码)可以替换成以下写法:
http.ListenAndServe(":8080", http.HandlerFunc(HelloServer))
2)fmt.Fprint和fmt.Fprintf都是用来写入http.ResponseWriter的不错的函数(他们实现了io.Writer)。
比如我们可以使用
fmt.Fprintf(w, "&h1&%s&h1&&div&%s&/div&", title, body)
来构建一个非常简单的网页并插入title和body的值
如果你需要更多复杂的替换,使用模板包(请看)
3)如果你需要使用安全的https连接,使用http.ListenAndServeTLS()代替http.ListenAndServe()
4)http.HandleFunc("/", Hfunc)中的HFunc是一个处理函数,如下:
func HFunc(w http.ResponseWriter, req *http.Request) {
也可以使用这种方式:http.Handle("/", http.HandlerFunc(HFunc))
上边的HandlerFunc只是一个类型名称,它定义如下:
type HandlerFunc func(ResponseWriter, *Request)
它是一个可以把普通的函数当做HTTP处理器的适配器。如果f函数声明的合适,HandlerFunc(f)就是一个执行了f函数的处理器对象。
http.Handle的第二个参数也可以是T的一个obj对象:http.Handle("/", obj)给T提供了ServeHTTP方法,实现了http的Handler接口:
func (obj *Typ) ServeHTTP(w http.ResponseWriter, req *http.Request) {
这个用法在类型Counter和Chan上使用过。只要实现了http.Handler,http包就可以处理任何HTTP请求。
练习 15.2:
编写一个网页服务器监听端口9999,有如下处理函数:
当请求http://localhost:9999/hello/Name时,响应:hello Name(Name需是一个合法的姓,比如Chris或者Madeleine)
当请求http://localhost:9999/shouthello/Name时,响应:hello NAME
练习 15.3:
创建一个空结构hello并使它实现http.Handler。运行并测试。

我要回帖

更多关于 go语言web服务器 的文章

 

随机推荐