• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

GoSocket实现简单的HttpServer

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

在上篇博客中写到如何用Python实现一个类似tomcat的简单服务器,接下来用go语言去实现

1. Go本身自己封装实现了非常简单的httpServer

package main

import (
    "bufio"
    "fmt"
    "io"
    "net/http"
    "os"
    "strings"
)

func main() {
    //http请求处理
    http.HandleFunc("/", handler1)
    //绑定监听地址和端口
    http.ListenAndServe("localhost:8080", nil)
}

//请求处理函数
func handler1(w http.ResponseWriter, r *http.Request) {
    //获取请求资源
    path := r.URL.Path
    if strings.Contains(path[1:], "") {
        //返回请求资源
        fmt.Fprintf(w, getHtmlFile("index.html"))
    } else {
        if strings.Contains(path[1:], ".html") {
            w.Header().Set("content-type", "text/html")
            fmt.Fprintf(w, getHtmlFile(path[1:]))
        }
        if strings.Contains(path[1:], ".css") {
            w.Header().Set("content-type", "text/css")
            fmt.Fprintf(w, getHtmlFile(path[1:]))
        }
        if strings.Contains(path[1:], ".js") {
            w.Header().Set("content-type", "text/javascript")
            fmt.Fprintf(w, getHtmlFile(path[1:]))
        }
        if strings.Contains(path[1:], "") {
            fmt.Print(strings.Contains(path[1:], ""))
        }
    }

}

func getHtmlFile(path string) (fileHtml string) {
    file, err := os.Open(path)
    if err != nil {
        panic(err)
    }
    defer file.Close()

    rd := bufio.NewReader(file)
    for {
        line, err := rd.ReadString('\n')

        if err != nil || io.EOF == err {
            break
        }
        fileHtml += line
    }
    return fileHtml
}

从上面的代码可以看出,关键的依赖是net/http,这个类库实现得非常好,而且支持并发,在这个就不去分析源码。

2. 但对于自己实现简易的服务器,最好还是用socket去实现:

实现之前还是需具备了解http等一些基础知识,因为上篇博客已经介绍了,所以在这里不介绍了 直接写代码

package main

import (
    "bufio"
    "fmt"
    "io"
    "log"
    "net"
    "os"
    "strings"
)

func main() {
    //确定协议及绑定IP及端口
    netListen, err := net.Listen("tcp", "localhost:8080")
    CheckError(err)
    defer netListen.Close()
    Log("waiting for client request")
    for {
        //接受请求连接
        conn, err := netListen.Accept()
        if err != nil {
            CheckError(err)
            break
        } else {
            Log(conn.RemoteAddr().String(), "tcp connect success")
            //处理请求连接
            handleConnection(conn)
        }
        conn.Close()
    }
}

//处理请求连接函数
func handleConnection(conn net.Conn) {
    buffer := make([]byte, 2048)
    n, err := conn.Read(buffer)
    if err != nil {
        Log(conn.RemoteAddr().String(), " connection error: ", err)
        conn.Close()
    } else {
        Log(conn.RemoteAddr().String(), "receive data string:\n", string(buffer[:n]))
        //返回数据给客户端
        responseInfoToClient(conn, string(buffer[:n]), err)
    }
}

//返回数据的函数
func responseInfoToClient(conn net.Conn, requestInfo string, err error) {
    //获取http协议头
    conn.Write([]byte(getFileContent("head.md")))
    conn.Write([]byte("\n"))
    var path string = strings.Replace(getMidStr(requestInfo, "GET /", "HTTP"), " ", "", -1)
    fmt.Println(path)
    if path != "" {
        if path == "favicon.ico" {
            fmt.Println("every connect hava favicon.ico resource request")
        } else {
            _, err = os.Open(path)
            if err != nil {
                fmt.Println("RESTful")
            } else {
                conn.Write([]byte(getFileContent(path)))
            }
        }
    } else {
        conn.Write([]byte(getFileContent("index.html")))
    }
}

func getMidStr(data string, startStr string, endStr string) (reqSouce string) {
    var startIndex int = strings.Index(data, startStr)
    var info string
    if startIndex >= 0 {
        startIndex += len(startStr)
        var endIndex int = strings.Index(data, endStr)
        info = data[startIndex:endIndex]
    }
    return info
}

func getFileContent(path string) (fileInfo string) {
    file, err := os.Open(path)
    if err != nil {
        panic(err)
    }
    defer file.Close()

    rd := bufio.NewReader(file)
    for {
        line, err := rd.ReadString('\n')

        if err != nil || io.EOF == err {
            break
        }
        fileInfo += line
    }
    return fileInfo
}

func Log(v ...interface{}) {
    log.Println(v...)
}

func CheckError(err error) {
    if err != nil {
        fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
        os.Exit(1)
    }
}

源码下载:https://github.com/Jiashengp/GoHttpServer


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Go并发编程实践发布时间:2022-07-10
下一篇:
Go 堆栈的理解发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap