zoukankan      html  css  js  c++  java
  • Go Socket实现简单的HttpServer

    在上篇博客中写到如何用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('
    ')
    
            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:
    ", 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("
    "))
        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('
    ')
    
            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

  • 相关阅读:
    mysql 中文字段排序( UTF8按拼音首字母排序)
    输入输出挂
    HDU 6301 贪心
    HDU1533 最小费用最大流
    POJ 2135 最小费用最大流 入门题
    HDU 6278 主席树(区间第k大)+二分
    HDU3549 最大流 裸题
    2018牛客网暑期ACM多校训练营(第一场)D图同构,J
    POJ 1804 逆序对数量 / 归并排序
    Codeforces Round #489 (Div. 2) B、C
  • 原文地址:https://www.cnblogs.com/jiashengmei/p/6371096.html
Copyright © 2011-2022 走看看