Jump to content
IPS Community Suite 简体中文

Search the Community

Showing results for tags 'golang'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Public docs
  • Server Softwares
    • IPS
    • WordPress
  • 其它
    • Scratch
    • Python
    • Ubuntu & LinuxMint
    • Softwares
    • WordPress Plugins

Blogs

  • Dev

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Found 5 results

  1. 本文记录在阿里云VPS 上,使用 Go 语言和 126 SMTP 免费服务发送必要邮件的实现。 安装 Golang 查看下是否安装过 whereis go 如果没有显示出路径,那么,这台服务器就没有安装过 Golang ,需要安装下,如果不是太确定服务器架构,可查看下: arch 如果看到的是 x86_64 ,那就是 64 位的系统,安装 Golang : wget https://redirector.gvt1.com/edgedl/go/go1.9.2.linux-amd64.tar.gz --no-check-certificate tar -C /usr/local -xzf go1.9.2.linux-amd64.tar.gz rm -f go1.9.2.linux-amd64.tar.gz 然后按照 Golang 官方说明,把 Golang 加入到环境变量中: export PATH=$PATH:/usr/local/go/bin 确定安装成功,执行: go version 如果看到相应的版本输出,说明成功了,如果没看到,不对,不可能看不到的啊。。。 SMTP 账号准备 以 126 邮箱为例:设置->POP3/SMTP/IMAP,点击页面左侧菜单中的 "客户端授权密码",设置下客户端授权码,记住它。 服务器防火墙允许 465 端口 以 CentOS 6.X 为例。 先查看下防火墙规则中是否启用了 465 端口: iptables -L -n 如果没有,添加 iptables -A INPUT -p tcp --dport 465 -j ACCEPT 保存 service iptables save 重启防火墙 service iptables restart Golang 邮件发送的测试脚本 本地创建个文件 mailtls.go /* 通过 SMTP 的 465 端口发送邮件 测试执行: go run mailtls.go */ package main import ( "crypto/tls" "fmt" "log" "net" "net/smtp" ) func main() { /*==============config================*/ userPlain := "XXX@126.com" pwdPlain := "xxxBJ" fromPlain := "xxx@126.com" toPlain := "xxx@qq.com" hostPlain := "smtp.126.com" portPlain := 465 /*==============//config================*/ fmt.Println("开始发送") auth := smtp.PlainAuth( "", userPlain, pwdPlain, hostPlain, ) to := []string{toPlain} msg := []byte("To: " + toPlain + "\r\n" + "Subject:一封 Golang 发出的邮件!!\r\n" + "\r\n" + "假装这是邮件内容!!\n世界,你好!\r\n") err := SendMailViaTLS( fmt.Sprintf("%s:%d", hostPlain, portPlain), auth, fromPlain, to, msg, ) if err != nil { log.Fatal(err) } else { fmt.Println("发送完毕!") } } func Dial(addr string) (*smtp.Client, error) { conn, err := tls.Dial("tcp", addr, nil) if err != nil { log.Println("Dialing Error:", err) return nil, err } host, _, _ := net.SplitHostPort(addr) return smtp.NewClient(conn, host) } func SendMailViaTLS(addr string, auth smtp.Auth, from string, to []string, msg []byte) (err error) { c, err := Dial(addr) if err != nil { log.Println("Create SMTP Client fail:", err) return err } defer c.Close() if auth != nil { if ok, _ := c.Extension("AUTH"); ok { if err = c.Auth(auth); err != nil { log.Println("AUTH ERROR ", err) return err } } } if err = c.Mail(from); err != nil { return err } for _, addr := range to { if err = c.Rcpt(addr); err != nil { return err } } w, err := c.Data() if err != nil { return err } _, err = w.Write(msg) if err != nil { return err } err = w.Close() if err != nil { return err } return c.Quit() } 按照自己的实际情况修改上面的配置 ( config 之间的内容),然后把文件上传到服务器的某个目录下。 打开服务器的模拟终端(一般是 XShell), 在文件所在目录执行: go run mailtls.go 如果看到: 开始发送 发送完毕! 说明邮件已发送,可以去自己的邮箱的收件夹或者垃圾邮件收件夹看下。
  2. Go 语言简介 准备 Go 首先是一种特别适用于网络服务器等基础设施类软件的,免费开源的静态编译型的编程语言。 在 Go 成为最成功的编程语言之前, C 是最成功的编程语言, 我不喜欢臃肿的 Java ,所以这儿不提它。 Go 的三个发明人 Robert Griesemer, Rob Pike 和 Ken Thompson, 在 Google 发明了这东西:2007年9月形成构想, 2009 年11月发布,2012 年发布 1.0 版本。 说到 Go 的时候, 除了指 Go 语言自身,还指其 CLI 工具, 编译器, 文档, 标准库,以及第三方使用 Go 语言写的库等。 Go 的标准库有100多个涉及I/O, 排序,文本处理等的包, 一个包由若干个.go 文件构成。 名为 main 的包特殊的,它不是库,而是定义了一个独立的可执行程序。 Go 的某些特性: 静态类型,编译语言,支持垃圾回收,包系统,一等函数,词法作用域,系统交互接口,字符串默认使用 UTF-8编码,并且不可变。 Go 有 25 个关键词, 18种数据类型。 一些使用 Go 的软件 基础软件 Docker 基础软件 ETCD 基础软件 Kubernetes 数据库 TiDB 数据库 InfulxDB 消息系统 NSQ 缓存系统 GroupCache 。。。 Web 框架或组件 第一名是Pat,其次是HttpRouter和Goji 。在重量级框架中,Gin 似乎是目前比较好的选择, Martini 在许多基准测试中都是所有测试路由器的性能最差的。Beego 似乎有一些可扩展性的问题,并且当参数或路由数量很多时,马尼蒂(Martini)的性能会更差,性能更差。 全功能框架 Revel Revel 借鉴了 Play! 这个框架, 它似乎将自己定位为“一站式解决方案”,大部分功能都是预先配置的,并安装了最佳功能。这意味着你可以在没有设置的情况下做很多事情,这对许多创业公司和小团队来说都很有吸引力。 Gin 这是一个非常简约的、精简的框架,它只包含最基本的功能、库和功能。据说比 Martini 快 39倍。它使用 httprouter 进行请求处理。 一个非常简朴的框架,因此不适用于需要大型后端或多个复杂服务器功能等高大上的应用场景。 Martini 出现的比较早的 Go 语言 web框架,在它上面集成第三方支持很容易,Martini 还对路由方法和格式提供了广泛的支持,并支持通配符、变量参数、regex限制等等, 这使得它比 Gin 更有力量。 Martini 有足够大的群众基础,很多问题容易被解决。 但是它最近一次维护是在 2014 年... Web.go 一个非常轻量级的框架. Beego 国人谢孟军做的一个工具化了的全功能 Web 框架,支持模块化开发,在国内很火,它有一个强大的ORM系统,但它在页面缓存(缓存了前几个版本的页面)和多第三方扩展的支持上有所欠缺。 Ego 一个基于 Gin 用 Go 编写的全栈 Web 框架,轻量级和高效的前端组件解决方案. 前端编译执行,不影响后端效率。 Iris http://iris-go.com/ 地球上最快的 Go 语言 Web 框架。 查阅 https://github.com/gin-gonic/go-http-routing-benchmark http://nordicapis.com/7-frameworks-to-build-a-rest-api-in-go/ https://github.com/diyan/go-web-framework-comparsion 可找到更多。 其它 How to include C code in your Go package https://dave.cheney.net/2013/09/07/how-to-include-c-code-in-your-go-package RxGo https://github.com/reactivex/rxgo Go ReactiveX Programming https://medium.com/@jochasinga/go-reactivex-programming-4a2d5e077ce9 Advanced Testing in Go https://about.sourcegraph.com/go/advanced-testing-in-go-mitchell-hashimoto 库 https://github.com/lukechampine/ply
  3. 本文演示使用 Go 语言实现基于 MySQL 数据库的程序,支持命令行工具的增删改查,增加 REST API 的增删查。 仅用于演示。 MySQL 在数据库 pfm 中创建需要的表 CREATE TABLE `pfm`.`userinfo` ( `uid` INT(10) NOT NULL AUTO_INCREMENT , `username` VARCHAR(64) NULL DEFAULT NULL , `departname` VARCHAR(64) NULL DEFAULT NULL , `created` DATE DEFAULT NULL , PRIMARY KEY (`uid`) ) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE TABLE `pfm`.`userdetail` ( `uid` INT(10) NOT NULL DEFAULT '0', `intro` TEXT NULL, `profile` TEXT NULL, PRIMARY KEY(`uid`) )ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci; Go package main import ( "fmt" "log" "os" "strconv" "strings" "database/sql" _ "github.com/go-sql-driver/mysql" "encoding/json" "net/http" "github.com/gorilla/mux" ) const ( dbHost string = "127.0.0.1" dbPort string = "3306" dbName string = "pfm" dbUserName string = "root" dbUserPassword string = "mysql" RestPort string = "6699" ) type Person struct { ID string `json:"id,omitempty"` Username string `json:"username,omitempty"` Departname string `json:"departname,omitempty"` Created string `json:"created,omitempty"` UserDetail *UserDetail `json:"userdetail,omitempty"` } type UserDetail struct { Intro string `json:"intro,omitempty"` Profile string `json:"proflie,omitempty"` } var people []Person func GetPersonEndpoint(w http.ResponseWriter, req *http.Request) { params := mux.Vars(req) for _, item := range people { if item.ID == params["id"] { json.NewEncoder(w).Encode(item) return } } SetHeader(w) json.NewEncoder(w).Encode(&Person{}) } func GetPeopleEndpoint(w http.ResponseWriter, req *http.Request) { SetHeader(w) json.NewEncoder(w).Encode(people) } func CreatePersonEndpoint(w http.ResponseWriter, req *http.Request) { /* params := mux.Vars(req)*/ var person Person _ = json.NewDecoder(req.Body).Decode(&person) /*数据库中创建*/ id:= Insert( person.Username, person.Departname) person.ID = strconv.Itoa(id) /* person.ID = aaa*/ people = append(people, person) SetHeader(w) json.NewEncoder(w).Encode(people) } func DeletePersonEndpoint(w http.ResponseWriter, req *http.Request) { params := mux.Vars(req) for index, item := range people { if item.ID == params["id"] { people = append(people[:index], people[index+1:]...) id,_ := strconv.Atoi(params["id"]) Delete(id) break } } SetHeader(w) json.NewEncoder(w).Encode(people) } func SetHeader(w http.ResponseWriter){ w.Header().Set("Content-Type", "application/json") } func getPeople(){ db, err := ConnectDB() checkErr(err) getTaskSQL := "select * from userinfo" rows, err := db.Query(getTaskSQL) var ( uid int username string departname string created string ) defer rows.Close() for rows.Next() { err := rows.Scan(&uid, &username, &departname, &created) if err != nil { log.Println(err) } /*获取userDetail*/ _,intro, profile := GetUserDetailByUid( uid) if len(intro)>1||len(profile)>1 { people = append(people, Person{ID: fmt.Sprintf("%d", uid), Username: username, Departname: departname,Created:created, UserDetail: &UserDetail{Profile: profile, Intro: intro}}) }else{ people = append(people, Person{ID: fmt.Sprintf("%d", uid), Username: username, Departname: departname,Created:created}) } } } func GetUserDetailByUid(id int)( int, string, string ) { db, err := ConnectDB() defer db.Close() checkErr(err) row := db.QueryRow("SELECT * FROM userdetail WHERE uid=?", id) var ( uid int intro string profile string ) err = row.Scan(&uid, &intro, &profile) if nil != err{ return uid ,intro, profile } return uid ,intro, profile } func checkErr(err error) { if err != nil { log.Println(err) panic(err) } } func ConnectDB() (*sql.DB, error) { db, err := sql.Open("mysql", dbUserName+":"+dbUserPassword+"@tcp("+dbHost+":"+dbPort+")/"+dbName+"?charset-utf8&sql_mode=TRADITIONAL") return db, err } func Insert(userName string, departName string) int { db, err := ConnectDB() if err != nil { log.Println("插入: 打开数据库出错") } else { log.Println("插入: 已打开数据库") } defer db.Close() checkErr(err) stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?") checkErr(err) res, err := stmt.Exec(userName, departName, "2017-02-05") checkErr(err) id, err := res.LastInsertId() checkErr(err) return int(id) } func Query(id int) (int, string, string, string) { db, err := ConnectDB() if err != nil { log.Println("查询: 打开数据库出错") } else { log.Println("查询:已打开数据库") } defer db.Close() checkErr(err) row := db.QueryRow("SELECT * FROM userinfo WHERE uid=?", id) var ( uid int username string departname string created string ) err = row.Scan(&uid, &username, &departname, &created) checkErr(err) return uid, username, departname, created } func GetAll() { db, err := ConnectDB() checkErr(err) getTaskSQL := "select * from userinfo" rows, err := db.Query(getTaskSQL) var ( uid int username string departname string created string ) defer rows.Close() fmt.Printf(strings.Repeat("*", 68) + "\n") fmt.Printf("%-4s\t%-16s\t%-16s\t%-20s\n", "ID", "名称", "部门", "创建时间") fmt.Printf(strings.Repeat("_", 68) + "\n") for rows.Next() { err := rows.Scan(&uid, &username, &departname, &created) if err != nil { log.Println(err) } fmt.Printf("%-4s\t%-16s\t%-16s\t%-20s", fmt.Sprintf("%d", uid), username, departname, created) fmt.Printf("\n") } fmt.Printf("\n" + strings.Repeat("*", 68)) } func Update(id int, uName string) { db, err := ConnectDB() if err != nil { log.Println("更新: 打开数据库出错") } else { log.Println("更新: 已打开数据库") } defer db.Close() checkErr(err) stmt, err := db.Prepare("UPDATE userinfo SET username=? WHERE uid=?") checkErr(err) res, err := stmt.Exec(uName, id) checkErr(err) affectedRows, err := res.RowsAffected() checkErr(err) /* int64 转换为 string fmt.Sprintf("%d", affectedRows) strconv.FormatInt(affectedRows,10) */ var affectedRowsCount string = fmt.Sprintf("%d", affectedRows) log.Println("更新了" + affectedRowsCount + "行数据") } func Delete(id int) { db, err := ConnectDB() if err != nil { log.Println("删除: 打开数据库出错") } else { log.Println("删除: 已打开数据库") } defer db.Close() checkErr(err) stmt, err := db.Prepare("DELETE FROM userinfo WHERE uid=?") checkErr(err) res, err := stmt.Exec(id) checkErr(err) affect, err := res.RowsAffected() checkErr(err) log.Println(affect) /* return true*/ } /* go build -o a.exe main.go && a */ func main() { if len(os.Args) > 2 { switch os.Args[1] { case "a": case "i": fmt.Println("开始添加") var id int = Insert(os.Args[2], os.Args[3]) var Id string = strconv.Itoa(id) fmt.Println("已添加为 " + Id) GetAll() case "u": fmt.Println("开始修改") /*id,_ := strconv.ParseInt(os.Args[2] ,10, 32)*/ id, _ := strconv.Atoi(os.Args[2]) Update(id, os.Args[3]) GetAll() case "d": fmt.Println("开始删除") id, _ := strconv.Atoi(os.Args[2]) Delete(id) GetAll() case "g": fmt.Println("开始查询") fmt.Println(os.Args) id, _ := strconv.Atoi(os.Args[2]) uid, username, departname, created := Query(id) log.Println(uid) log.Println(username) log.Println(departname) log.Println(created) } } else { GetAll() router := mux.NewRouter() /* 运行后对数据库的修改不能及时反馈,也就是说查询是一次性的。 */ getPeople() /* [{"id":"22","username":"李四光","departname":"销售部门"},{"id":"23","username":"张三","departname":"科技"},{"id":"24","username":"李四","departname":"销售"},{"id":"25","username":"马兵地","departname":"总办"},{"id":"27","username":"吕桂花","departname":"公关部"}] */ router.HandleFunc("/people", GetPeopleEndpoint).Methods("GET") router.HandleFunc("/people/{id}", GetPersonEndpoint).Methods("GET") /*创建*/ /* { "Username":"王雁平", "Departname":"总办" } */ router.HandleFunc("/people/", CreatePersonEndpoint).Methods("POST") /*删除*/ router.HandleFunc("/people/{id}", DeletePersonEndpoint).Methods("DELETE") fmt.Println("\n") fmt.Println("浏览器打开 \nhttp://localhost:"+RestPort+"/people\n") fmt.Println("可用的链接 \nhttp://localhost:"+RestPort+"/people/uid\n") log.Fatal(http.ListenAndServe(":"+RestPort, router)) } } 编译 go build -o a.exe main.go CLI 添加记录 a i 张二麻子 科技部 //或者 a a 张二麻子 科技部 CLI 修改记录 a u 25 吕桂花 CLI 删除指定ID的记录 a d 25 CLI 按给定ID查询单个记录 a g 27 CLI 查询全部记录 不需要添加额外的参数: REST API 查看全部记录 GET http://localhost:6699/people 查看指定ID 的记录 GET http://localhost:6699/people/id 删除指定ID的记录 http://localhost:6699/people/id 增加记录 POST http://localhost:6699/people/ 增加记录的示例数据 { "Username":"雁平", "Departname":"总办" }
  4. C 语言的实现 /* gcc main.c && a */ #include <stdio.h> void multiTable_v1(){ int i; int j; for(i=1;i<=9;i++){ for (j=1;j<=9;j++){ printf("%d*%d=%2d\t",i,j,i*j); } printf("\n"); } } void multiTable_v2(){ int i; int j; for(i=1;i<=9;i++){ for (j=1;j<=9;j++){ if(j<i){ printf(" "); }else{ printf("%d*%d=%2d\t",i,j,i*j); } } printf("\n"); } } void multiTable_v3(){ int i; int j; for(i=1;i<=9;i++){ for (j=1;j<=9;j++){ if(j>i){ printf(" "); }else{ printf("%d*%d=%2d\t",i,j,i*j); } } printf("\n"); } } void multiTable_v4(){ int i, j,n; for(i=1;i<=9;i++){ for (n=1;n<=9-i;n++){ printf(" "); } for (j=1;j<=9;j++){ printf("%d*%d=%2d\t",i,j,i*j); } printf("\n"); } } int main() { printf("\nVer1\n"); printf("\n********\n"); multiTable_v1(); printf("\nVer2\n"); printf("\n********\n"); multiTable_v2(); printf("\nVer 3\n"); printf("\n********\n"); multiTable_v3(); printf("\nVer 4\n"); printf("\n********\n"); multiTable_v4(); return 0; } Go 语言的实现 /* go build -o b.exe main.go && b */ package main import "fmt" func multiTable_v1() { var ( i int j int ) for i = 1; i <= 9; i++ { for j = 1; j <= 9; j++ { fmt.Printf("%d*%d=%2d\t", i, j, i*j) } fmt.Printf("\n") } } func multiTable_v2() { var ( i int j int ) for i = 1; i <= 9; i++ { for j = 1; j <= 9; j++ { if j < i { fmt.Printf(" ") } else { fmt.Printf("%d*%d=%2d\t", i, j, i*j) } } fmt.Printf("\n") } } func multiTable_v3() { var ( i int j int ) for i = 1; i <= 9; i++ { for j = 1; j <= 9; j++ { if j > i { fmt.Printf(" ") } else { fmt.Printf("%d*%d=%2d\t", i, j, i*j) } } fmt.Printf("\n") } } func multiTable_v4() { var ( i int j int n int ) for i = 1; i <= 9; i++ { for n = 1; n <= 9-i; n++ { fmt.Printf(" ") } for j = 1; j <= 9; j++ { fmt.Printf("%d*%d=%2d\t", i, j, i*j) } fmt.Printf("\n") } } func main() { fmt.Printf("\nVer1\n") fmt.Printf("\n********\n") multiTable_v1() fmt.Printf("\nVer2\n") fmt.Printf("\n********\n") multiTable_v2() fmt.Printf("\nVer3\n") fmt.Printf("\n********\n") multiTable_v3() fmt.Printf("\nVer 4\n") fmt.Printf("\n********\n") multiTable_v4() } C 和 Go 都是要打印乘法表, 编译为 Windows 操作系统的可执行文件后: C 编译的可执行程序是 53KB; Go 编译的可执行程序是 1604KB;
  5. 简介 这是一个使用 Go 语言写的 CLI 小工具,用于生成和运行 TypeScript 项目。 它依赖 TypeScript, npm, Git, Sublime Text。 特性 支持使用 Git 进行版本管理; 支持热更新, 使用如下模块: gulp-cli browserify tsify vinyl-source-stream watchify gulp-util typescript gulp gulp-typescript http-server 自动生成 tsconfig.json 和所需的 gulpfile.js; 使用 生成项目 tsp g [项目目录名] [主类名] [项目名称] 为指定的项目运行 HTTP 服务器: tsp s [项目目录] [端口] 帮助命令 tsp h 查看版本号: tsp v 用例: tsp g test12 Test12Class 测试项目12 执行后: ****************开始****************** Wrote to Y:\DevSpace\Go\tsp\test12\package.json: { "name": "test12", "version": "1.0.0", "description": "", "main": "gulpfile.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" } Initialized empty Git repository in Y:/DevSpace/Go/tsp/test12/.git/ [master (root-commit) 9cab961] init 7 files changed, 104 insertions(+) create mode 100644 .gitignore create mode 100644 _script.sh create mode 100644 gulpfile.js create mode 100644 package.json create mode 100644 src/index.html create mode 100644 src/main.ts create mode 100644 tsconfig.json ****************完成****************** 项目test12已生成!!! 生成的项目目录 test12 下的目录和文件: 项目生成后,在 CLI 执行: tsc s test12 6666 tsp 会基于 test12 项目下的 dist 目录,运行一个简单的 HTTP server。 再打开一个 CLI 窗口,执行: gulp 以在浏览器中同步你的代码变化。 开源 https://github.com/suifengtec/tsp git clone https://github.com/suifengtec/tsp 或者 mkdir tsp && cd tsp && go install github.com/suifengtec/tsp 可拉取该项目。 下载 https://raw.githubusercontent.com/suifengtec/tsp/master/tsp.exe
×