1、GO语言实现的简单TCP服务代码

package main

import (
"net"
"fmt"
) var (
maxRead = 1100
msgStop = []byte("cmdStop")
msgStart = []byte("cmdContinue")
)
func main() {
hostAndPort := "localhost:54321"
listener := initServer(hostAndPort) for {
conn, err := listener.Accept()
checkError(err, "Accept: ")
go connectionHandler(conn)
}
} func initServer(hostAndPort string) *net.TCPListener {
serverAddr, err := net.ResolveTCPAddr("tcp", hostAndPort)
checkError(err, "Resolving address:port failed: '" + hostAndPort + "'")
listener, err := net.ListenTCP("tcp", serverAddr)
checkError(err, "ListenTCP: ")
println("Listening to: ", listener.Addr().String())
return listener
} func connectionHandler(conn net.Conn) {
connFrom := conn.RemoteAddr().String()
println("Connection from: ", connFrom)
talktoclients(conn)
for {
var ibuf []byte = make([]byte, maxRead + 1)
length, err := conn.Read(ibuf[0:maxRead])
ibuf[maxRead] = 0 // to prevent overflow
  switch err {
    case nil:
     handleMsg(length, err, ibuf)     default:
     goto DISCONNECT
  }
}
DISCONNECT:
err := conn.Close()
println("Closed connection:" , connFrom)
checkError(err, "Close:" )
} func talktoclients(to net.Conn) {
wrote, err := to.Write(msgStart)
checkError(err, "Write: wrote " + string(wrote) + " bytes.")
} func handleMsg(length int, err error, msg []byte) {
if length > 0 { for i := 0; ; i++ {
if msg[i] == 0 {
break
}
}
fmt.Printf("Received data: %v", string(msg[0:length]))
fmt.Println(" length:",length)
} } func checkError(error error, info string) {
if error != nil {
    panic("ERROR: " + info + " " + error.Error()) // terminate program
  }
}

例2 、

下面先创建一个简单的Server端:

package main

import (
"net"
"fmt"
) func main() {
if ln, err := net.Listen("tcp", ":8080"); err == nil {
defer ln.Close()
for{
ln.Accept()
fmt.Println("Receive a Message")
}
}
}

和脚本一样简单的写法。

先net.Listen(), 第一个参数是协议,tcp还是udp,第二个参数是ip地址,这里可以不填写IP只填写端口就是

使用defer 来Close,将close写在listen之后是个好习惯

然后再循环中使用Accept()接受消息

下面是一个可以进行压力测试的客户端程序

package main

import (
"net"
"fmt"
) func main() {
currency := 20 //并发数,记住,一个连接数是打开一个端口号,window和linux的端口号都是有限制的
count := 10 //每条连接发送多少次连接 for i:=0;i<currency;i++ {
go func(){
for j:=0;j<count;j++ {
sendMessage()
}
}()
}
select{}
} func sendMessage() {
conn, err := net.Dial("tcp", "127.0.0.1:8080") if(err != nil) {
panic("error")
} header := "GET / HTTP/1.0\r\n\r\n"
fmt.Fprintf(conn, header)
}

2、Go语言中使用MySql

首先安装mysql的go语言驱动

go get github.com/ziutek/mymysql/godrv

演示代码

package users

import (
"database/sql"
"fmt"
_ "github.com/ziutek/mymysql/godrv"
) const (
DB_NAME = "mysql_database_name"
DB_USER = "mysql_user"
DB_PASS = "mysql_password"
) type User struct {
Id int `json:"id"`
Name string `json:"name"`
Alias string `json:"alias"`
} func OpenDB() *sql.DB {
db, err := sql.Open("mymysql", fmt.Sprintf("%s/%s/%s", DB_NAME, DB_USER, DB_PASS))
if err != nil {
panic(err)
}
return db
} func UserById(id int) User {
db := OpenDB()
defer db.Close()
row := db.QueryRow("SELECT `id`, `name`,`alias` FROM `users` WHERE id=?", id)
user := new(User)
row.Scan(&user.Id, &user.Name, &user.Alias)
return user
}

例2:

go的sql包是在pkg/database中,里面的两个包sqlsql/driver可以一起看。建议看这个两个包之前可以先看看sql文件夹下的doc.txt。这个文档说了几点比较重要的:

1 这两个包是真正Go风格的包。

2 这使用这两个包就不需要关于并发处理了,也不需要维护自己的数据库连接池了,一旦建立了一个连接,这个连接是可以在各个goroutine之间共用的。

sql/driver提供的是数据库的接口,具体的实现还需要自己实现。

一、先看database/driver包

第一个用到的方法是Register

这个方法将实现了driver.Driver的驱动注册到变量drivers中,当写完一个驱动之后,就需要将驱动注册到sql中才能使用sql包中的这些接口。这个实现了driver.Driver的必须实现了Open方法.

driver.Open返回的是driver.Conn,它的三个方法

Prepare : 参数绑定

Close : 关闭连接

Begin : 支持事务

先看Prepare,这个和php mysql pdo一样的用法

Conn.Prepare("select * from test where a=?")

返回的Stmt结构:

Close : 关闭这个statement

NumInput : 返回有多少个可以绑定的参数

Exec : Insert或者update等无返回的使用

Query :select等查询操作使用

Exec是绑定变量,然后返回Result结构

Query是绑定变量,然后返回Rows结果集

看Result里面的方法:

LastInsertId()  : Insert操作之后获取到的主键id

RowsAffect() : 影响到的行数

Rows:

Columns() : 返回的数据有哪些列,其实就是返回的表列名

Close() : 关闭Rows,调用之后不能再进行任何操作

Next() : 将下一行的数据取到des[] Value中。这里的Value接口可以是int64,float64,bool,[]byte,string,time.Time

下面回到Begin,返回了Tx

开始事务之后除了查询之外,就两种行为:Commit和Rollback,这两种行为都是Tx接口的方法

drvier中的结构全是接口性质的,它需要你来实现并注册到Register中。

二、驱动的具体使用是在database/sql中

首先将几个sql的结构看一遍

首先sql中的结构都是对driver中的结构进行了一层封装,比如像Rows,有个内部属性是rowsi driver.Rows。

对sql的实际操作都是使用driver.Rows里面的接口进行操作的,实际也就是使用你自己实现的driver进行操作。

driver和sql就像插头和一个充满插头的汽车一样,你实现了driver,即实现了这些插头的配置,你就可使用sql这个汽车了。

Result : 和driver中的Result一致,即你如果实现了driver.Result,那你自然就实现了sql.Result。它是个接口,其实没有什么特殊的用处,如果sql包中的所有Result都换成driver.Result也是行的,估计是作者希望返回值不要引用到其他包去,就使用这种方法。

Rows :  基于了driver.Rows, 还在上面扩展了几个其他的方法。拥有方法:

Close

Cloumns

Err

Next

Scan

Stmt :基于driver.Stmt。拥有方法

Close

Exec

Query

QueryRow

Tx:基于driver.Tx。拥有方法:

Commit

Exec

Prepare

Query

QueryRow

Rollback

Stmt

从sql.Open开始

返回了sql.DB结构,这个结构是实现了driver.Conn结构,除了Conn已有的Prepare,Begin,Close之外,还直接多了几个查询方法:

Driver() : 返回当前驱动

Exec() : 直接进行操作

Query() : 进行查询,返回Rows

QueryRow() : 预期返回单行,返回Row

不管Rows还是Row都有个很好用的方法Scan来将数据放到制定的变量中去。

比如下面就是典型的Rows用法

rows, err := db.Query("SELECT ...")
... for rows.Next() {
var id int
var name string err = rows.Scan(&id, &name)
...
}

Prepare返回Stmt结构

Exec返回Result结构

至于这几个结构也有各自的方法。

go-mysql的更多相关文章

  1. Hadoop 中利用 mapreduce 读写 mysql 数据

    Hadoop 中利用 mapreduce 读写 mysql 数据   有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...

  2. mysql每秒最多能插入多少条数据 ? 死磕性能压测

    前段时间搞优化,最后瓶颈发现都在数据库单点上. 问DBA,给我的写入答案是在1W(机械硬盘)左右. 联想起前几天infoQ上一篇文章说他们最好的硬件写入速度在2W后也无法提高(SSD硬盘) 但这东西感 ...

  3. LINUX篇,设置MYSQL远程访问实用版

    每次设置root和远程访问都容易出现问题, 总结了个通用方法, 关键在于实用 step1: # mysql -u root mysql mysql> Grant all privileges o ...

  4. nodejs进阶(6)—连接MySQL数据库

    1. 建库连库 连接MySQL数据库需要安装支持 npm install mysql 我们需要提前安装按mysql sever端 建一个数据库mydb1 mysql> CREATE DATABA ...

  5. MySQL高级知识- MySQL的架构介绍

    [TOC] 1.MySQL 简介 概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而 ...

  6. 闰秒导致MySQL服务器的CPU sys过高

    今天,有个哥们碰到一个问题,他有一个从库,只要是启动MySQL,CPU使用率就非常高,其中sys占比也比较高,具体可见下图. 注意:他的生产环境是物理机,单个CPU,4个Core. 于是,他抓取了CP ...

  7. 我的MYSQL学习心得(一) 简单语法

    我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  8. Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制

    将通用的序列号生成器库 从SQL Server迁移到Mysql 遇到的一个问题,就是TimeStamp/RowVersion并发控制类型在非Microsoft SQL Server数据库中的实现.SQ ...

  9. Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境

    首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...

  10. 当忘记mysql数据库密码时如何进行修改

    因为长时间没有使用数据库了,或者把密码改完之后就忘了数据库密码,不能正常进入数据库,也无法修改密码,有一个简单的常用修改密码方式: 1.首先找到和打开mysql.exe和mysqld.exe所在的文件 ...

随机推荐

  1. LA 3907 Puzzle

    问题描述:先给你s个禁止串,求不包含禁止串的最长串,如果存在,打印字典序最大. 数据范围:s <= 1000, 禁止串长度不超过50. 分析:不匹配问题实际上等同于匹配问题.假设我们已经有满足条 ...

  2. 验证码识别--type7

    验证码识别--type7 一.干扰分析 有黑色边框,然后点干扰,线干扰 去边框 去点干扰 变成这样的结果,方便运算吗?也可以多种方式联合起来运算的.我相信在很多情况下,都可能会遇到类似的结果.我们人类 ...

  3. JAVA基础知识之JVM-——使用反射生成并操作对象

    Class对象可以获取类里的方法,由Method对象表示,调用Method的invoke可以执行对应的方法:可以获取构造器,由Constructor对象表示,调用Constructor对象的newIn ...

  4. AIM Tech Round 3 (Div. 2) B

    Description Vasya takes part in the orienteering competition. There are n checkpoints located along ...

  5. qbxt十一系列二

    PA[题目描述]汉诺塔升级了:现在我们有N个圆盘和N个柱子,每个圆盘大小都不一样,大的圆盘不能放在小的圆盘上面,N个柱子从左到右排成一排.每次你可以将一个柱子上的最上面的圆盘移动到右边或者左边的柱子上 ...

  6. maven之一——多模块项目构建

    参考这个帖子: http://www.cnblogs.com/xdp-gacl/p/4242221.html

  7. EXCEL中讲 10分10秒转换成610秒

    前几天宝贝跟我打赌100W说我20天给她打电话不到10小时,我说绝对超过10小时了,但是由于宝贝的赖皮死活不承认,所以我被迫掉出通话记录,拿到通话记录我有点小郁闷,因为通话记录里的时间格式00分00秒 ...

  8. C# Eval()和Bind()

    Eval( " ")和Bind( " ") 这两种一个单向绑定,一个双向绑定,bind是双向绑定,但需数据源支持ASP.NET   2.0改善了模板中的数据绑定 ...

  9. 【转载】Linux的进程间通信-信号量

    原文:Linux的进程间通信-信号量 Linux的进程间通信-信号量 版权声明: 本文章内容在非商业使用前提下可无需授权任意转载.发布. 转载.发布请务必注明作者和其微博.微信公众号地址,以便读者询问 ...

  10. 程序间数据共享与传递:EXPORT/IMPORT、SAP/ABAP Memory

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...