分类 Go 下的文章

“Go是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。 罗伯特·格瑞史莫、罗勃·派克及肯·汤普逊于2007年9月开始设计Go,稍后伊恩·兰斯·泰勒、拉斯·考克斯加入项目。Go是基于Inferno操作系统所开发的。”

1、需要使用到的go-sqlite 的 github地址

https://github.com/mattn/go-sqlite3

2、安装go-sqlite

go get github.com/mattn/go-sqlite3

提示:
Important: because this is a CGO enabled package you are required to set the environment variable CGO_ENABLED=1 and have a gcc compile present within your path.

3、示例代码

package main

import (
    "database/sql"
    "fmt"
    "log"
    "os"

    _ "github.com/mattn/go-sqlite3"
)

func main() {
    os.Remove("./foo.db")

    db, err := sql.Open("sqlite3", "./foo.db")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    sqlStmt := `
    create table foo (id integer not null primary key, name text);
    delete from foo;
    `
    _, err = db.Exec(sqlStmt)
    if err != nil {
        log.Printf("%q: %s\n", err, sqlStmt)
        return
    }

    tx, err := db.Begin()
    if err != nil {
        log.Fatal(err)
    }
    stmt, err := tx.Prepare("insert into foo(id, name) values(?, ?)")
    if err != nil {
        log.Fatal(err)
    }
    defer stmt.Close()
    for i := 0; i < 10; i++ {
        _, err = stmt.Exec(i, fmt.Sprintf("https://const.net.cn %03d", i))
        if err != nil {
            log.Fatal(err)
        }
    }
    tx.Commit()

    rows, err := db.Query("select id, name from foo")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()
    for rows.Next() {
        var id int
        var name string
        err = rows.Scan(&id, &name)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(id, name)
    }
    err = rows.Err()
    if err != nil {
        log.Fatal(err)
    }

    stmt, err = db.Prepare("select name from foo where id = ?")
    if err != nil {
        log.Fatal(err)
    }
    defer stmt.Close()
    var name string
    err = stmt.QueryRow("3").Scan(&name)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(name)

    _, err = db.Exec("delete from foo")
    if err != nil {
        log.Fatal(err)
    }

    _, err = db.Exec("insert into foo(id, name) values(1, 'const'), (2, 'net'), (3, 'cn')")
    if err != nil {
        log.Fatal(err)
    }

    rows, err = db.Query("select id, name from foo")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()
    for rows.Next() {
        var id int
        var name string
        err = rows.Scan(&id, &name)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(id, name)
    }
    err = rows.Err()
    if err != nil {
        log.Fatal(err)
    }
}

4、编译运行

CGO_ENABLED=1 GOOS=linux go run .

运行结果:

0 https://const.net.cn 000
1 https://const.net.cn 001
2 https://const.net.cn 002
3 https://const.net.cn 003
4 https://const.net.cn 004
5 https://const.net.cn 005
6 https://const.net.cn 006
7 https://const.net.cn 007
8 https://const.net.cn 008
9 https://const.net.cn 009
https://const.net.cn 003
1 const
2 net
3 cn

5、go sqlite3 arm64/aarch64

env CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++  CGO_ENABLED=1 GOOS=linux GOARCH=arm64 GOARM=7  go build -v 

Go语言里面提供了net/http包,我们通过http包来搭建一个的Web服务器。

package main
import(
    "fmt"
    "net/http"
    "log"
    "os"
    "os/signal"
    "syscall"
)

func sayhelloName(w http.ResponseWriter, r *http.Request) {        
    w.Header().Set("Content-Type", "text/html; charset=utf-8")
    fmt.Fprintf(w,"<hr/>")
    fmt.Fprintf(w, "<h1>Hello https://const.net.cn!</h1>")
}    

func main(){
    fmt.Println("first web server demo.")
    // 创建系统信号接收器
    done := make(chan os.Signal)
    signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
    go func() {
        <-done 
        fmt.Println("Shutdown server")
        os.Exit(1)
    }()
    fs := http.FileServer(http.Dir("e:/")) 
    http.Handle("/static/", http.StripPrefix("/static/", fs))
    http.HandleFunc("/", sayhelloName) 
    err := http.ListenAndServe(":8080", nil) 
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

访问http://127.0.0.1:8080/

效果如下:
2021-06-12_170307.png

访问http://127.0.0.1:8080/static/
效果如下:
2021-06-12_170344.png

1、登录页面html

<!DOCTYPE HTML>
<html class="no-js">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="renderer" content="webkit">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>登录</title>
        <meta name="robots" content="noindex, nofollow">
<link rel="stylesheet" href="/static/css/style.css?v=17.10.30">
  </head>
    <body class="body-100">

<div class="typecho-login-wrap">
    <div class="typecho-login">
        <form action="" method="post" name="login" role="form">
            <p>
                <label for="name" class="sr-only">用户名</label>
                <input type="text" id="name" name="username" value="" placeholder="用户名" class="text-l w-100" autofocus />
            </p>
            <p>
                <label for="password" class="sr-only">密码</label>
                <input type="password" id="password" name="password" class="text-l w-100" placeholder="密码" />
            </p>
            <p class="submit">
                <button type="submit" class="btn btn-l w-100 primary">登录</button>
            </p>
        </form>        
    </div>
</div>
    </body>
</html>

2、处理网站登录以及获取http post数据,验证密码功能

package main

import (
    "fmt"
    "html/template"
    "log"
    "net/http"
    "strings"
    "time"
)

type Item struct {
    Name  string
    Price int
}

func logouthanler(w http.ResponseWriter, r *http.Request) {
    expiredTime := time.Now()
    c1 := &http.Cookie{
        Name:     "username",
        Expires: expiredTime,
        MaxAge:   -1,
        HttpOnly: true,
    }

    http.SetCookie(w, c1)
}

// 登陆页面
func loginhanler(w http.ResponseWriter, r *http.Request) {

    // 如果是post请求,注意先后顺序
    if r.Method == http.MethodPost {
        // 解析表单 并且校验
        r.ParseForm()
        for k, v := range r.Form {
            fmt.Println("key:", k)
            fmt.Println("val:", strings.Join(v, "-"))
        }
        userName := r.FormValue("username")
        pwd := r.FormValue("password")
        fmt.Println("userName:", userName)
        fmt.Println("pwd:", pwd)

        // 如果输入正确,则发送cookie 并给出反馈
        if userName == "const" && pwd == "const" {

            c1 := &http.Cookie{
                Name:     "username",
                Value:    userName,
                MaxAge:   0,
                HttpOnly: true,
            }

            http.SetCookie(w, c1)

            //fmt.Fprint(w, "登陆成功")
            http.Redirect(w, r, "/manage", http.StatusFound)
        } else {
            fmt.Fprint(w, "登陆失败")
        }

        // 显示登录页面
    } else {
        // 解析模板
        t, err := template.ParseFiles("index.html")
        if err != nil {
            log.Fatal(err)
        }
           t.Execute(w, "")
    }    
}   
func manageHandler(w http.ResponseWriter, r *http.Request) {
    username, err := r.Cookie("username")
    if err != nil || username.Value == "" {
        http.Redirect(w, r, "/", http.StatusFound)
    }

    fmt.Println("enter manage1")
    t, err := template.ParseFiles("manage.html")
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("enter manage2")
    t.Execute(w, username.Value)
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", loginhanler)
    mux.HandleFunc("/login", loginhanler)
    mux.HandleFunc("/manage", manageHandler)
    mux.HandleFunc("/logout", logouthanler)
    fs := http.FileServer(http.Dir("."))
    mux.Handle("/static/", http.StripPrefix("/static/", fs))

    server := &http.Server{
        Addr:    ":8080",
        Handler: mux,
    }

    err := server.ListenAndServe()
    if err != nil {
        log.Fatal(err)
    }

}

3、登录效果
2021-06-14_201101.png

2021-06-14_201143.png

// 生产者:生成factor整数倍的序列
    
func Producer(factor int, out chan<- int) {
        
for i := 0; ; i++ {
            
out <- i*factor
        
}}
    
// 消费者
    
func Consumer(in <-chan int) {
        
for v := range in {
            
fmt.Println(v)
        
}}
    
func main() {
        
ch := make(chan int, 64) // 成果队列
      
go Producer(3, ch) // 生成3的倍数的序列
    
go Producer(5, ch) // 生成5的倍数的序列
        
go Consumer(ch)    // 消费生成的队列
      
// 运行一定时间后退出
        
time.Sleep(5 * time.Second)}

在golang中使用cgo调用openssl库的md5方法,最简单的方法

package main

/*
#cgo CFLAGS: -I ./include
#cgo LDFLAGS: -L ./lib -lcrypto
#include <stdlib.h>
#include <openssl/md5.h>
*/
import "C"

import (
    "encoding/hex"
    "fmt"
    "strings"
    "unsafe"
)

func main() {

    fmt.Println("go openssl md5 demo.")
    data := []byte("const.net.cn")
    md := make([]byte, 16)
    C.MD5((*C.uchar)(unsafe.Pointer(&data[0])), C.size_t(len(data)), (*C.uchar)(unsafe.Pointer(&md[0])))
    md5Str := hex.EncodeToString(md)
    md5Str = strings.ToUpper(md5Str)
    fmt.Printf("md5Str = %s\n", md5Str)
}

输出:

go run .
go openssl md5 demo.
md5Str = FA8424A7B72EB90BF04685205ECC5760
echo -n "const.net.cn" | md5sum 
fa8424a7b72eb90bf04685205ecc5760  -