Golang 文件服务器小结

花了一个星期学习文件服务器,老是在一些地方搞混,整理一下所学的,清晰了不少。

学Go半个月,还有很多不懂的地方,有理解错误的,还望高手指出。

注:以下代码中,w为http.ResponseWriter类型, r为*http.Request类型

1、先该清楚一些类型的意义:

Handler:处理请求和生成返回的接口。其实就是接口。

ServerMux:路由,也是一种Handler。还是接口。

Request:用户的请求信息,用来解析用户的请求信息包括,POST、GET、Cookie、URL等信息。

Response:服务器需要反馈给用户端的信息。

ResponseWriter:生成Response的接口。也还是接口

Conn:网络连接。

ServerMux有map表,map的key是r.URL.String(),而Value记录的是一个方法,这个方法与ServeHTTP是一样的,也叫HandlerFunc。另一个方法是Handle 用来注册HandlerFunc。

ServeMUx实现Handler接口,充当http.ListenAndServe()的第二个参数。

http.ListenAndServe()的第二个参数是Handle接口,实现配置外部路由器(也就是非默认的路由器)。

2、设置路由的方法:

(1)

func  fooHandler(w,r){  }

http.Handle("/foo", fooHandler)//此处是http.Handle,而不是http.Handler

(2)

http.HandleFunc("/foo",  func(w,r){

//处理

})

以上配置的是默认路由

如果自己使用了ServeMux作为路由,就得用其他配置方法了

(3)配置ServeMux路由

1)

mux:=http.NewServeMux()

mux.Handle("/foo",&fooHandler{})//第二个参数是一个Handler,可以是定义一个Handler接口,也可以是返回Handler的函数。比如:StripPrefix(prefix string, h Handler) Handler {}等。

type  fooHandler  struct{}

func  (*fooHandler)serveHTTP(w,r){

//处理

}

2)

mux:=http.NewServeMux()

mux.HandleFunc("/foo", fooHandler)

func  fooHandler(w,r){

//处理

}

3)

Var  mux  map[string] func(w,r)

mux=make[string]func(w,r)

mux["/foo"]=fooHandler

func fooHandler(w,r){

}

再定义一个Handler作为默认的handler,实现路由

type myHandler  struct{}

func  (*myHandler)ServeHTTP(w,r){

if h,ok:=mux[r.URL.String()];ok{  //注意mux[]的匹配。需要的时候,要用path包,比如我就用到了mux[path.Dir(r.URL.path)]。

h(w,r)

return

}

}

server自己定义:

server:=http.Server{

Addr: ":9090",
        Handler: &myhandler{},  //myhandler在这里使用
        ReadTimeout: 5 * time.Second,
}

3、简单文件服务器实现的三种方法

(1)

 1 package main
 2
 3 import (
 4     "fmt"
 5     "log"
 6     "net/http"
 7 )
 8
 9 func sayHello(w http.ResponseWriter, r *http.Request) {
10     fmt.Fprintf(w, "%v", "Hello,this is from FileServer1.") //输出到客户端
11 }
12 func main() {
13     http.HandleFunc("/", sayHello)
14     err := http.ListenAndServe(":9090", nil) //使用默认handler = DefaultServeMux
15     if err != nil {
16         log.Fatal("ListenAndServe: ", err)
17     }
18 }

FileServer1

(2)

 1 package main
 2
 3 import (
 4     "fmt"
 5     "log"
 6     "net/http"
 7 )
 8
 9 type myhandler struct {
10 }
11
12 func sayHello(w http.ResponseWriter, r *http.Request) {
13     fmt.Fprintf(w, "%v", "Hello,this is from FileServer2.")
14 }
15 func (*myhandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
16     fmt.Fprintf(w, "%v", "Bye,this is from FileServer2.")
17 }
18
19 func main() {
20     mux := http.NewServeMux()
21     mux.Handle("/b", &myhandler{})
22     mux.HandleFunc("/", sayHello)
23     err := http.ListenAndServe(":9090", mux)
24     if err != nil {
25         log.Fatal("ListenAndServe: ", err)
26     }
27 }

(3)

 1 package main
 2
 3 import (
 4     "fmt"
 5     "log"
 6     "net/http"
 7     "time"
 8 )
 9
10 type myhandler struct {
11 }
12
13 var mux map[string]func(http.ResponseWriter, *http.Request)
14
15 func sayHello(w http.ResponseWriter, r *http.Request) {
16     fmt.Fprintf(w, "%v", "Hello,this is from FileServer3.")
17 }
18 func (*myhandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
19     if h, ok := mux[r.URL.String()]; ok {
20         h(w, r)
21         return
22     }
23 }
24
25 func main() {
26     server := http.Server{
27         Addr:        ":9090",
28         Handler:     &myhandler{},
29         ReadTimeout: 5 * time.Second,
30     }
31     mux = make(map[string]func(http.ResponseWriter, *http.Request))
32     mux["/"] = sayHello
33     err := server.ListenAndServe()
34     if err != nil {
35         log.Fatal("ListenAndServe: ", err)
36     }
37 }

时间: 2024-10-10 08:25:18

Golang 文件服务器小结的相关文章

Golang vs PHP 之文件服务器

前面的话 作者为golang脑残粉,本篇内容可能会引起phper不适,请慎读! 前两天有同事遇到一个问题,需要一个能支持上传.下载功能的HTTP服务器做一个数据中心.我刚好弄过,于是答应帮他搭一个. HTTP服务器,首先想到的就是PHP + nginx.于是开撸,先写一个PHP的上传 <?php if ($_FILES["file"]["error"] > 0) { echo "错误:: " . $_FILES["file&

golang 服务平滑重启小结

背景 golang 程序平滑重启框架 supervisor 出现 defunct 原因 使用 master/worker 模式 背景 在业务快速增长中,前期只是验证模式是否可行,初期忽略程序发布重启带来的暂短停机影响.当模式实验成熟之后会逐渐放量,此时我们的发布停机带来的影响就会大很多.我们整个服务都是基于云,请求流量从 四层->七层->机器. 要想实现平滑重启大致有三种方案,一种是在流量调度的入口处理,一般的做法是 ApiGateway + CD ,发布的时候自动摘除机器,等待程序处理完现有

纯golang爬虫实战-(五-小结篇)

对前几篇文章的代码进行梳理,形成4个通用型函数: 1 直接Get或Post,通常会被网站限制访问: 2 带headers进行Get或Post,模拟了浏览器,通常可以正常访问. 代码(注意由于下面的代码中设置http header时有*/*,造成代码的显示不太正常,但不影响): //Header是直接从chrome console中复制的view source形式的Request Headers,注意只包括以冒号分割的内容. //FormData也是直接从chrome console中复制的vie

Golang基础_12-基础小结

目录 目录 注意事项 time的Format函数参数使用常量,不要使用字符串 在for range闭包里使用goroutine注意:要传参数进去 目录 @ 注意事项 package main表示当前脚本是程序入口,含有main函数 如果不是入口,只是单纯的一个包的话,就尽量与当前目录文件夹的名称保持一致,表示一个包的脚本 slice的append函数的真面目 slicez作为参数传递时是引用类型的,也就是把地址传进去了,要是做了一般的修改,就是真的修改了 package main import

golang中字符串的查找方法小结

1)func Contains(s, substr string) bool这个函数是查找某个字符是否在这个字符串中存在,存在返回true 示例如下: import ( "fmt" "strings" ) func main() { fmt.Println(strings.Contains("widuu", "wi")) //true fmt.Println(strings.Contains("wi", &

golang解析mongodb中的ISODate类型

在golang中可以使用time.Time数据类型来保存mongodb中的ISODate时间. g type Model struct {     uploadDate time.Time `bson:"uploadDate"` } m := Model{} if err := c.Find(nil).Select({"_id": 0, "uploadDate": 1}).One(&m); err != nil {     fmt.Pri

Golang后台开发初体验

转自:http://blog.csdn.net/cszhouwei/article/details/37740277 补充反馈 slice 既然聊到slice,就不得不提它的近亲array,这里不太想提值类型和引用类型的概念(个人觉得其实都是值类型),golang的array其实可以假想为C的struct类型,只是struct通过变量名来访问成员(如xxx.yyy),而array通过下标来访问成员(如xxx[3]),具体内存布局如下图所示: 图 1 golang的array内存布局 显然gola

互联网世界中的C语言——我的golang学习笔记:1(基础语法快速过)

前言 学习任何知识都会有一个学习背景 最近,我们团队乃至我司整个云服务,上go的呼声越来越高!新服务已经开始用go开发,部分现有Java版的服务重构为go也只是时间问题而已,故相关技术积累势在必行!在云网络的分布式服务乃至在一切高并发,分布式后台服务中,golang都有着很大的优势. 据我对国内互联网行业的实际考察,了解,目前国内主流互联网公司都在积极投入go的怀抱…… 青云更是全栈使用了go…… 还有火的一塌糊涂的docker. 它为云而生. 它为并发而生. 还有go的安全.简洁.高效 有良好

java并发包小结(一)

java.util.concurrent 包含许多线程安全.高性能的并发构建块.换句话讲,创建 java.util.concurrent 的目的就是要实现 Collection 框架对数据结构所执行的并发操作.通过提供一组可靠的.高性能并发构建块,开发人员可以提高并发类的线程安全.可伸缩性.性能.可读性和可靠性. JDK 5.0 中的并发改进可以分为三组:    1. JVM 级别更改.大多数现代处理器对并发对某一硬件级别提供支持,通常以 compare-and-swap (CAS)指令形式.C