1 // main 2 package main 3 4 import ( 5 "fmt" 6 "runtime" 7 "sync" 8 ) 9 10 func main() {11 fmt.Println("Hello World!")12 runtime.GOMAXPROCS(1)13 var wg sync.WaitGroup14 wg.Add(2)15 i := 99916 fmt.Println("Start Goroutines")17 18 go func() {19 defer wg.Done()20 //共享变量 i wg21 fmt.Println(i)22 for count := 0; count < 3; count++ {23 for char := 'a'; char < 'a'+26; char++ {24 fmt.Printf("%c ", char)25 }26 }27 }()28 29 go func() {30 defer wg.Done()31 fmt.Println(i)32 for count := 0; count < 3; count++ {33 for char := 'A'; char < 'A'+26; char++ {34 fmt.Printf("%c ", char)35 }36 }37 }()38 39 fmt.Println("Waiting to Finish")40 wg.Wait()41 42 fmt.Println("\nTerminating Program")43 }
go 协程练习
接口练习
1 // Sample program to show what happens when the outer and inner 2 // type implement the same interface. 3 package main 4 5 import ( 6 "fmt" 7 ) 8 9 // notifier is an interface that defined notification10 // type behavior.11 type notifier interface {12 notify()13 }14 15 // user defines a user in the program.16 type user struct {17 name string18 email string19 }20 21 // notify implements a method that can be called via22 // a value of type user.23 func (u *user) notify() {24 fmt.Printf("Sending user email to %s<%s>\n",25 u.name,26 u.email)27 }28 29 // admin represents an admin user with privileges.30 type admin struct {31 user32 level string33 }34 35 // notify implements a method that can be called via36 // a value of type Admin.37 func (a *admin) notify() {38 fmt.Printf("Sending admin email to %s<%s>\n",39 a.name,40 a.email)41 }42 43 // main is the entry point for the application.44 func main() {45 // Create an admin user.46 ad := admin{47 user: user{48 name: "john smith",49 email: "john@yahoo.com",50 },51 level: "super",52 }53 54 // Send the admin user a notification.55 // The embedded inner type's implementation of the56 // interface is NOT "promoted" to the outer type.57 sendNotification(&ad)58 59 // We can access the inner type's method directly.60 ad.user.notify()61 62 // The inner type's method is NOT promoted.63 ad.notify()64 }65 66 // sendNotification accepts values that implement the notifier67 // interface and sends notifications.68 func sendNotification(n notifier) {69 n.notify()70 }
work代码注释 《go语言编程实战》
1 package work 2 3 import "sync" 4 5 //接口 6 type Worker interface { 7 Task() 8 } 9 10 //pool结构体11 type Pool struct {12 work chan Worker13 wg sync.WaitGroup14 }15 16 //new函数 返回 pool指针17 func New(maxGorountines int) *Pool {18 p := Pool{19 work: make(chan Worker),20 }21 //wg添加wait数量22 p.wg.Add(maxGorountines)23 for i := 0; i < maxGorountines; i++ {24 go func() {25 //执行POOL内的任务 完成后wg执行done26 for w := range p.work {27 w.Task()28 }29 p.wg.Done()30 }()31 }32 33 return &p34 }35 36 //将任务放入POOL37 func (p *Pool) Run(w Worker) {38 p.work <- w39 }40 41 //关闭POOL42 func (p *Pool) Shutdown() {43 close(p.work)44 p.wg.Wait()45 }
1 // main 2 package main 3 4 import ( 5 "fmt" 6 "log" 7 "sync" 8 "time" 9 "work"10 )11 12 var names = []string{13 "steve",14 "bob",15 "mary",16 "therese",17 "jason",18 }19 20 type namePrinter struct {21 name string22 }23 24 func (m *namePrinter) Task() {25 log.Println(m.name)26 time.Sleep(time.Second)27 }28 29 func main() {30 fmt.Println("Hello World!")31 p := work.New(2)32 33 var wg sync.WaitGroup34 wg.Add(100 * len(names))35 36 for i := 0; i < 100; i++ {37 for _, name := range names {38 np := namePrinter{39 name: name,40 }41 go func() {42 p.Run(&np)43 wg.Done()44 }()45 }46 }47 wg.Wait()48 p.Shutdown()49 }
runner代码注释 《go语言编程实战》
1 // runner 2 package runner 3 4 import ( 5 "errors" 6 "fmt" 7 "os" 8 "os/signal" 9 "time"10 )11 12 //runner结构体13 type Runner struct {14 interrupt chan os.Signal15 complete chan error16 timeout <-chan time.Time17 tasks []func(int)18 }19 20 //错误变量121 var Errtimeout = errors.New("received timeout")22 //错误变量223 var ErrInterrupt = errors.New("received interrupt")24 25 //runner的new函数26 func New(d time.Duration) *Runner {27 return &Runner{28 interrupt: make(chan os.Signal, 1),29 complete: make(chan error),30 timeout: time.After(d),31 }32 }33 34 //func(int)加入 runner35 func (r *Runner) Add(tasks ...func(int)) {36 r.tasks = append(r.tasks, tasks...)37 }38 39 40 //goroutine执行 结果超时或者错误 成功41 func (r *Runner) Start() error {42 signal.Notify(r.interrupt, os.Interrupt)43 44 go func() {45 r.complete <- r.run()46 }()47 48 select {49 case err := <-r.complete:50 return err51 case <-r.timeout:52 return Errtimeout53 }54 }55 56 //run函数 遍历函数数组57 //若发生错误中断则返回 中断错误58 func (r *Runner) run() error {59 for id, task := range r.tasks {60 if r.gotInterrupt() {61 return ErrInterrupt62 }63 task(id)64 }65 return nil66 }67 68 //通过interrupt接受中断69 func (r *Runner) gotInterrupt() bool {70 select {71 case <-r.interrupt:72 signal.Stop(r.interrupt)73 return true74 default:75 return false76 }77 }78 79 80 //无用main函数81 func main() {82 fmt.Println("Hello World!")83 84 }
1 // main 2 package main 3 4 import ( 5 "fmt" 6 "log" 7 "os" 8 "runner" 9 "time"10 )11 12 const timeout = 3 * time.Second13 14 func main() {15 fmt.Println("Hello World!")16 log.Println("Starting work.")17 18 r := runner.New(timeout)19 20 r.Add(createTask(), createTask(), createTask())21 22 if err := r.Start(); err != nil {23 switch err {24 case runner.Errtimeout:25 log.Println("Terminating due to timeout")26 os.Exit(1)27 case runner.ErrInterrupt:28 log.Println("Terminating due to interrupt")29 os.Exit(2)30 }31 }32 log.Println("Process ended")33 }34 35 func createTask() func(int) {36 return func(id int) {37 log.Printf("processor - Task #%d", id)38 time.Sleep(time.Duration(id) * time.Second)39 }40 }
go语言编程 代码修改
1 package library 2 3 //music 记录 4 type MusicEntry struct { 5 Id string 6 Name string 7 Artist string 8 Source string 9 Type string10 }
1 package library 2 3 import "errors" 4 5 //音乐管理器 音乐记录数组 6 type MusicManager struct { 7 musics []MusicEntry 8 } 9 10 //返回音乐管理器指针11 func NewMusicManager() *MusicManager {12 return &MusicManager{make([]MusicEntry, 0)}13 }14 15 //返回音乐管理器 音乐数组的元素数16 func (m *MusicManager) Len() int {17 return len(m.musics)18 }19 20 //输入索引 获取音乐记录指针21 func (m *MusicManager) Get(index int) (music *MusicEntry, err error) {22 if index < 0 || index >= len(m.musics) {23 return nil, errors.New("Index out of range.")24 }25 return &m.musics[index], nil26 }27 28 29 //根据名字字符串 查找音乐记录的指针30 func (m *MusicManager) Find(name string) *MusicEntry {31 if len(m.musics) == 0 {32 return nil33 }34 35 for _, m := range m.musics {36 if m.Name == name {37 return &m38 }39 }40 return nil41 }42 43 //添加音乐记录 输入音乐记录指针44 func (m *MusicManager) Add(music *MusicEntry) {45 46 m.musics = append(m.musics, *music)47 }48 49 50 //输入索引 移除指定索引 返回音乐记录指针51 func (m *MusicManager) Remove(index int) *MusicEntry {52 if index < 0 || index >= len(m.musics) {53 return nil54 }55 56 removedMusic := &m.musics[index]57 58 // Remove the found item from the slice.59 if index < len(m.musics)-1 { // Element between first and last60 m.musics = append(m.musics[:index-1], m.musics[index+1:]...)61 } else if index == 0 { // empty it.62 m.musics = make([]MusicEntry, 0)63 } else { // The last element64 m.musics = m.musics[:index-1]65 }66 67 return removedMusic68 }69 70 71 72 //输入名字字符串 移除符合的音乐记录 返回音乐记录指针73 func (m *MusicManager) RemoveByName(name string) *MusicEntry {74 if len(m.musics) == 0 {75 return nil76 }77 78 for i, v := range m.musics {79 if v.Name == name {80 return m.Remove(i)81 }82 }83 return nil84 }
1 package library 2 3 import "testing" 4 5 func TestOps(t *testing.T) { 6 mm := NewMusicManager() 7 if mm == nil { 8 t.Error("NewMusicManager failed") 9 }10 11 if mm.Len() != 0 {12 t.Error("NewMusicManager failed,not empty")13 }14 15 m0 := &MusicEntry{ "1", "MyHeart", "Celion", "http://wwww", "pop"}16 mm.Add(m0)17 18 if mm.Len() != 1 {19 t.Error("MusicManager Add() failed")20 }21 22 m := mm.Find(m0.Name)23 if m == nil {24 t.Error("MusicManager Find() failed")25 }26 27 if m.Id != m0.Id || m.Name != m0.Name ||28 m.Artist != m0.Artist || m.Source != m0.Source ||29 m.Type != m0.Type {30 t.Error("MusicManager Find() failed.Found item mismatch")31 }32 33 m, err := mm.Get(0)34 if m == nil || err != nil {35 t.Error("MusicManager Get() failed")36 }37 38 m = mm.Remove(0)39 if m == nil || mm.Len() != 0 {40 t.Error("MusicManager Remove() failed")41 }42 43 }
服务器 代码备份
1 // main 2 package main 3 4 import ( 5 //"crypto/cipher" 6 //"bufio" 7 "bytes" 8 "crypto/aes" 9 "encoding/binary" 10 "errors" 11 "fmt" 12 "log" 13 "net" 14 ) 15 16 var g_string string 17 18 type Header struct { 19 flag byte 20 packageLen int32 21 } 22 23 //字节转换成整形 24 func BytesToInt(b []byte) int { 25 bytesBuffer := bytes.NewBuffer(b) 26 27 var x int32 28 binary.Read(bytesBuffer, binary.LittleEndian, &x) 29 30 return int(x) 31 } 32 33 func recvBuf(conn net.Conn, buf []byte) (int, error) { 34 n, err := conn.Read(buf) 35 return n, err 36 } 37 38 func recvHeader(conn net.Conn) (int, error) { 39 headerbuf := make([]byte, 5) 40 //fmt.Println("before buf:", headerbuf) 41 42 n, err := recvBuf(conn, headerbuf) 43 if err != nil || n != 5 { 44 fmt.Println("err:", err) 45 return -1, err 46 } 47 //fmt.Println("after buf:", headerbuf, " n:", n) 48 if headerbuf[0] != '|' { 49 fmt.Println("err:flag error,exit!") 50 return -2, err 51 } 52 n = BytesToInt(headerbuf[1:]) 53 return n, err 54 } 55 56 func recvBody(conn net.Conn, n int) (int, error) { 57 var err = errors.New(" closed") 58 buf := make([]byte, n) 59 60 n, err = recvBuf(conn, buf) 61 if err != nil || n <= 0 { 62 fmt.Println("err:", err) 63 return -1, err 64 } 65 //buf 解密 66 mainecb(buf) 67 68 return n, err 69 } 70 71 func handleConn(conn net.Conn) { 72 fmt.Println("Enter func handleConn") 73 defer conn.Close() 74 who := conn.RemoteAddr().String() 75 fmt.Println(who) 76 for { 77 n, err := recvHeader(conn) 78 //fmt.Println("recvHeader n = ", n, " ", err) 79 if n <= 0 || err != nil { 80 var ErrEOF = errors.New("EOF") 81 if err == ErrEOF { 82 fmt.Println("err eauql") 83 } 84 fmt.Println("err:recvHeader error,exit! ,err:", err) 85 break 86 } 87 _, err = recvBody(conn, n) 88 } 89 90 } 91 92 //=============================================== 93 //ecb 94 //=============================================== 95 //AES ECB模式的加密解密 96 type AesTool struct { 97 //128 192 256位的其中一个 长度 对应分别是 16 24 32字节长度 98 Key []byte 99 BlockSize int100 }101 102 func (this *AesTool) Decrypt(src []byte) ([]byte, error) {103 //key只能是 16 24 32长度104 block, err := aes.NewCipher([]byte(this.Key))105 if err != nil {106 return nil, err107 }108 //返回加密结果109 decryptData := make([]byte, len(src))110 //存储每次加密的数据111 tmpData := make([]byte, this.BlockSize)112 113 //分组分块加密114 for index := 0; index < len(src); index += this.BlockSize {115 block.Decrypt(tmpData, src[index:index+this.BlockSize])116 //copy(decryptData, tmpData)117 decryptData = mergeByteArray(decryptData, tmpData)118 }119 return this.PKCS5UnPadding(decryptData), nil120 }121 122 func mergeByteArray(a []byte, b []byte) []byte {123 alen := len(a)124 blen := len(b)125 126 z := make([]byte, alen+blen)127 128 for i := 0; i < alen; i++ {129 z[i] = a[i]130 }131 for i := 0; i < blen; i++ {132 z[alen+i] = b[i]133 }134 return z135 }136 137 //unpadding138 func (this *AesTool) unPadding(src []byte) []byte {139 for i := len(src) - 1; ; i-- {140 if src[i] != 0 {141 return src[:i+1]142 }143 }144 return nil145 }146 147 func (this *AesTool) PKCS5Padding(ciphertext []byte, blockSize int) []byte {148 padding := blockSize - len(ciphertext)%blockSize149 padtext := bytes.Repeat([]byte{ byte(padding)}, padding)150 return append(ciphertext, padtext...)151 }152 153 func (this *AesTool) PKCS5UnPadding(origData []byte) []byte {154 length := len(origData)155 // 去掉最后一个字节 unpadding 次156 unpadding := int(origData[length-1])157 origData = origData[:(length - unpadding)]158 fmt.Println("origData inner:", string(origData))159 return origData160 }161 162 func mainecb(encryptData []byte) {163 //key := []byte{'#', '2', '&', '*', '#', ....}164 blickSize := 16165 tool := NewAesTool(key, blickSize)166 decryptData, _ := tool.Decrypt(encryptData)167 fmt.Println(string(decryptData))168 }169 func NewAesTool(key []byte, blockSize int) *AesTool {170 return &AesTool{Key: key, BlockSize: blockSize}171 }172 173 //====================================================174 //var global_int = 99175 176 func main() {177 fmt.Println("Hello World!")178 179 listener, err := net.Listen("tcp", "192.。。。")180 if err != nil {181 log.Fatal(err)182 }183 for {184 conn, err := listener.Accept()185 if err != nil {186 log.Println(err)187 continue188 }189 go handleConn(conn)190 }191 192 fmt.Println("net finish...")193 }