// main
package main import (
"fmt"
"runtime"
"sync"
) func main() {
fmt.Println("Hello World!")
runtime.GOMAXPROCS()
var wg sync.WaitGroup
wg.Add()
i :=
fmt.Println("Start Goroutines") go func() {
defer wg.Done()
//共享变量 i wg
fmt.Println(i)
for count := ; count < ; count++ {
for char := 'a'; char < 'a'+; char++ {
fmt.Printf("%c ", char)
}
}
}() go func() {
defer wg.Done()
fmt.Println(i)
for count := ; count < ; count++ {
for char := 'A'; char < 'A'+; char++ {
fmt.Printf("%c ", char)
}
}
}() fmt.Println("Waiting to Finish")
wg.Wait() fmt.Println("\nTerminating Program")
}
go 协程练习
接口练习
// Sample program to show what happens when the outer and inner
// type implement the same interface.
package main import (
"fmt"
) // notifier is an interface that defined notification
// type behavior.
type notifier interface {
notify()
} // user defines a user in the program.
type user struct {
name string
email string
} // notify implements a method that can be called via
// a value of type user.
func (u *user) notify() {
fmt.Printf("Sending user email to %s<%s>\n",
u.name,
u.email)
} // admin represents an admin user with privileges.
type admin struct {
user
level string
} // notify implements a method that can be called via
// a value of type Admin.
func (a *admin) notify() {
fmt.Printf("Sending admin email to %s<%s>\n",
a.name,
a.email)
} // main is the entry point for the application.
func main() {
// Create an admin user.
ad := admin{
user: user{
name: "john smith",
email: "john@yahoo.com",
},
level: "super",
} // Send the admin user a notification.
// The embedded inner type's implementation of the
// interface is NOT "promoted" to the outer type.
sendNotification(&ad) // We can access the inner type's method directly.
ad.user.notify() // The inner type's method is NOT promoted.
ad.notify()
} // sendNotification accepts values that implement the notifier
// interface and sends notifications.
func sendNotification(n notifier) {
n.notify()
}
work代码注释 《go语言编程实战》
package work import "sync" //接口
type Worker interface {
Task()
} //pool结构体
type Pool struct {
work chan Worker
wg sync.WaitGroup
} //new函数 返回 pool指针
func New(maxGorountines int) *Pool {
p := Pool{
work: make(chan Worker),
}
//wg添加wait数量
p.wg.Add(maxGorountines)
for i := ; i < maxGorountines; i++ {
go func() {
//执行POOL内的任务 完成后wg执行done
for w := range p.work {
w.Task()
}
p.wg.Done()
}()
} return &p
} //将任务放入POOL
func (p *Pool) Run(w Worker) {
p.work <- w
} //关闭POOL
func (p *Pool) Shutdown() {
close(p.work)
p.wg.Wait()
}
// main
package main import (
"fmt"
"log"
"sync"
"time"
"work"
) var names = []string{
"steve",
"bob",
"mary",
"therese",
"jason",
} type namePrinter struct {
name string
} func (m *namePrinter) Task() {
log.Println(m.name)
time.Sleep(time.Second)
} func main() {
fmt.Println("Hello World!")
p := work.New() var wg sync.WaitGroup
wg.Add( * len(names)) for i := ; i < ; i++ {
for _, name := range names {
np := namePrinter{
name: name,
}
go func() {
p.Run(&np)
wg.Done()
}()
}
}
wg.Wait()
p.Shutdown()
}
runner代码注释 《go语言编程实战》
// runner
package runner import (
"errors"
"fmt"
"os"
"os/signal"
"time"
) //runner结构体
type Runner struct {
interrupt chan os.Signal
complete chan error
timeout <-chan time.Time
tasks []func(int)
} //错误变量1
var Errtimeout = errors.New("received timeout")
//错误变量2
var ErrInterrupt = errors.New("received interrupt") //runner的new函数
func New(d time.Duration) *Runner {
return &Runner{
interrupt: make(chan os.Signal, ),
complete: make(chan error),
timeout: time.After(d),
}
} //func(int)加入 runner
func (r *Runner) Add(tasks ...func(int)) {
r.tasks = append(r.tasks, tasks...)
} //goroutine执行 结果超时或者错误 成功
func (r *Runner) Start() error {
signal.Notify(r.interrupt, os.Interrupt) go func() {
r.complete <- r.run()
}() select {
case err := <-r.complete:
return err
case <-r.timeout:
return Errtimeout
}
} //run函数 遍历函数数组
//若发生错误中断则返回 中断错误
func (r *Runner) run() error {
for id, task := range r.tasks {
if r.gotInterrupt() {
return ErrInterrupt
}
task(id)
}
return nil
} //通过interrupt接受中断
func (r *Runner) gotInterrupt() bool {
select {
case <-r.interrupt:
signal.Stop(r.interrupt)
return true
default:
return false
}
} //无用main函数
func main() {
fmt.Println("Hello World!") }
// main
package main import (
"fmt"
"log"
"os"
"runner"
"time"
) const timeout = * time.Second func main() {
fmt.Println("Hello World!")
log.Println("Starting work.") r := runner.New(timeout) r.Add(createTask(), createTask(), createTask()) if err := r.Start(); err != nil {
switch err {
case runner.Errtimeout:
log.Println("Terminating due to timeout")
os.Exit()
case runner.ErrInterrupt:
log.Println("Terminating due to interrupt")
os.Exit()
}
}
log.Println("Process ended")
} func createTask() func(int) {
return func(id int) {
log.Printf("processor - Task #%d", id)
time.Sleep(time.Duration(id) * time.Second)
}
}
go语言编程 代码修改
package library //music 记录
type MusicEntry struct {
Id string
Name string
Artist string
Source string
Type string
}
musicentry
package library import "errors" //音乐管理器 音乐记录数组
type MusicManager struct {
musics []MusicEntry
} //返回音乐管理器指针
func NewMusicManager() *MusicManager {
return &MusicManager{make([]MusicEntry, )}
} //返回音乐管理器 音乐数组的元素数
func (m *MusicManager) Len() int {
return len(m.musics)
} //输入索引 获取音乐记录指针
func (m *MusicManager) Get(index int) (music *MusicEntry, err error) {
if index < || index >= len(m.musics) {
return nil, errors.New("Index out of range.")
}
return &m.musics[index], nil
} //根据名字字符串 查找音乐记录的指针
func (m *MusicManager) Find(name string) *MusicEntry {
if len(m.musics) == {
return nil
} for _, m := range m.musics {
if m.Name == name {
return &m
}
}
return nil
} //添加音乐记录 输入音乐记录指针
func (m *MusicManager) Add(music *MusicEntry) { m.musics = append(m.musics, *music)
} //输入索引 移除指定索引 返回音乐记录指针
func (m *MusicManager) Remove(index int) *MusicEntry {
if index < || index >= len(m.musics) {
return nil
} removedMusic := &m.musics[index] // Remove the found item from the slice.
if index < len(m.musics)- { // Element between first and last
m.musics = append(m.musics[:index-], m.musics[index+:]...)
} else if index == { // empty it.
m.musics = make([]MusicEntry, )
} else { // The last element
m.musics = m.musics[:index-]
} return removedMusic
} //输入名字字符串 移除符合的音乐记录 返回音乐记录指针
func (m *MusicManager) RemoveByName(name string) *MusicEntry {
if len(m.musics) == {
return nil
} for i, v := range m.musics {
if v.Name == name {
return m.Remove(i)
}
}
return nil
}
manager
package library import "testing" func TestOps(t *testing.T) {
mm := NewMusicManager()
if mm == nil {
t.Error("NewMusicManager failed")
} if mm.Len() != {
t.Error("NewMusicManager failed,not empty")
} m0 := &MusicEntry{"", "MyHeart", "Celion", "http://wwww", "pop"}
mm.Add(m0) if mm.Len() != {
t.Error("MusicManager Add() failed")
} m := mm.Find(m0.Name)
if m == nil {
t.Error("MusicManager Find() failed")
} if m.Id != m0.Id || m.Name != m0.Name ||
m.Artist != m0.Artist || m.Source != m0.Source ||
m.Type != m0.Type {
t.Error("MusicManager Find() failed.Found item mismatch")
} m, err := mm.Get()
if m == nil || err != nil {
t.Error("MusicManager Get() failed")
} m = mm.Remove()
if m == nil || mm.Len() != {
t.Error("MusicManager Remove() failed")
} }
manager_test
服务器 代码备份
// main
package main import (
//"crypto/cipher"
//"bufio"
"bytes"
"crypto/aes"
"encoding/binary"
"errors"
"fmt"
"log"
"net"
) var g_string string type Header struct {
flag byte
packageLen int32
} //字节转换成整形
func BytesToInt(b []byte) int {
bytesBuffer := bytes.NewBuffer(b) var x int32
binary.Read(bytesBuffer, binary.LittleEndian, &x) return int(x)
} func recvBuf(conn net.Conn, buf []byte) (int, error) {
n, err := conn.Read(buf)
return n, err
} func recvHeader(conn net.Conn) (int, error) {
headerbuf := make([]byte, )
//fmt.Println("before buf:", headerbuf) n, err := recvBuf(conn, headerbuf)
if err != nil || n != {
fmt.Println("err:", err)
return -, err
}
//fmt.Println("after buf:", headerbuf, " n:", n)
if headerbuf[] != '|' {
fmt.Println("err:flag error,exit!")
return -, err
}
n = BytesToInt(headerbuf[:])
return n, err
} func recvBody(conn net.Conn, n int) (int, error) {
var err = errors.New(" closed")
buf := make([]byte, n) n, err = recvBuf(conn, buf)
if err != nil || n <= {
fmt.Println("err:", err)
return -, err
}
//buf 解密
mainecb(buf) return n, err
} func handleConn(conn net.Conn) {
fmt.Println("Enter func handleConn")
defer conn.Close()
who := conn.RemoteAddr().String()
fmt.Println(who)
for {
n, err := recvHeader(conn)
//fmt.Println("recvHeader n = ", n, " ", err)
if n <= || err != nil {
var ErrEOF = errors.New("EOF")
if err == ErrEOF {
fmt.Println("err eauql")
}
fmt.Println("err:recvHeader error,exit! ,err:", err)
break
}
_, err = recvBody(conn, n)
} } //===============================================
//ecb
//===============================================
//AES ECB模式的加密解密
type AesTool struct {
//128 192 256位的其中一个 长度 对应分别是 16 24 32字节长度
Key []byte
BlockSize int
} func (this *AesTool) Decrypt(src []byte) ([]byte, error) {
//key只能是 16 24 32长度
block, err := aes.NewCipher([]byte(this.Key))
if err != nil {
return nil, err
}
//返回加密结果
decryptData := make([]byte, len(src))
//存储每次加密的数据
tmpData := make([]byte, this.BlockSize) //分组分块加密
for index := ; index < len(src); index += this.BlockSize {
block.Decrypt(tmpData, src[index:index+this.BlockSize])
//copy(decryptData, tmpData)
decryptData = mergeByteArray(decryptData, tmpData)
}
return this.PKCS5UnPadding(decryptData), nil
} func mergeByteArray(a []byte, b []byte) []byte {
alen := len(a)
blen := len(b) z := make([]byte, alen+blen) for i := ; i < alen; i++ {
z[i] = a[i]
}
for i := ; i < blen; i++ {
z[alen+i] = b[i]
}
return z
} //unpadding
func (this *AesTool) unPadding(src []byte) []byte {
for i := len(src) - ; ; i-- {
if src[i] != {
return src[:i+]
}
}
return nil
} func (this *AesTool) PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
} func (this *AesTool) PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
// 去掉最后一个字节 unpadding 次
unpadding := int(origData[length-])
origData = origData[:(length - unpadding)]
fmt.Println("origData inner:", string(origData))
return origData
} func mainecb(encryptData []byte) {
//key := []byte{'#', '2', '&', '*', '#', ....}
blickSize :=
tool := NewAesTool(key, blickSize)
decryptData, _ := tool.Decrypt(encryptData)
fmt.Println(string(decryptData))
}
func NewAesTool(key []byte, blockSize int) *AesTool {
return &AesTool{Key: key, BlockSize: blockSize}
} //====================================================
//var global_int = 99 func main() {
fmt.Println("Hello World!") listener, err := net.Listen("tcp", "192.。。。")
if err != nil {
log.Fatal(err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Println(err)
continue
}
go handleConn(conn)
} fmt.Println("net finish...")
}