tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/examples/net/snake/main.go (about) 1 // This example is the classic snake network test. The snake is feed a steady 2 // diet of pkts and the pkts work themselves thru the snake segments and exit 3 // the tail. Each snake segment is a TCP socket connection to a server. The 4 // server echos pkts received back to the snake, and serves each segment on a 5 // different port. (See server/main.go for server). 6 // 7 // snake | server 8 // | 9 // head ----->---|-->--+ 10 // seg a | | 11 // +---<-|--<--+ 12 // | | 13 // +-->--|-->--+ 14 // seg b | | 15 // +---<-|--<--+ 16 // | | 17 // +-->--|-->--+ 18 // seg c | | 19 // +---<-|--<--+ 20 // | | 21 // +-->--|-->--+ 22 // ... | | 23 // +---<-|--<--+ 24 // | | 25 // +-->--|-->--+ 26 // seg n | | 27 // tail -------<-|--<--+ 28 // | 29 30 // The snake segments are linked by channels and each segment is run as a go 31 // func. This forces segments to connect and run concurrently, which is a good 32 // test of the underlying driver's ability to handle concurrent connections. 33 34 //go:build ninafw || wioterminal 35 36 package main 37 38 import ( 39 _ "embed" 40 "fmt" 41 "log" 42 "net" 43 "strings" 44 "time" 45 ) 46 47 //go:embed main.go 48 var code string 49 50 var ( 51 server string = "10.0.0.100:8080" 52 ) 53 54 func segment(in chan []byte, out chan []byte) { 55 var buf [512]byte 56 for { 57 c, err := net.Dial("tcp", server) 58 for ; err != nil; c, err = net.Dial("tcp", server) { 59 println(err.Error()) 60 time.Sleep(5 * time.Second) 61 } 62 for { 63 select { 64 case msg := <-in: 65 _, err := c.Write(msg) 66 if err != nil { 67 log.Fatal(err.Error()) 68 } 69 time.Sleep(100 * time.Millisecond) 70 n, err := c.Read(buf[:]) 71 if err != nil { 72 log.Fatal(err.Error()) 73 } 74 out <- buf[:n] 75 } 76 } 77 } 78 } 79 80 func feedit(head chan []byte) { 81 for i := 0; i < 100; i++ { 82 head <- []byte(fmt.Sprintf("\n---%d---\n", i)) 83 for _, line := range strings.Split(code, "\n") { 84 if len(line) == 0 { 85 line = " " 86 } 87 head <- []byte(line) 88 } 89 } 90 } 91 92 var head = make(chan []byte) 93 var a = make(chan []byte) 94 var b = make(chan []byte) 95 var c = make(chan []byte) 96 var d = make(chan []byte) 97 var e = make(chan []byte) 98 var f = make(chan []byte) 99 var tail = make(chan []byte) 100 101 func main() { 102 103 // The snake 104 go segment(head, a) 105 go segment(a, b) 106 go segment(b, c) 107 go segment(c, d) 108 go segment(d, e) 109 go segment(e, f) 110 go segment(f, tail) 111 112 go feedit(head) 113 114 for { 115 select { 116 case msg := <-tail: 117 println(string(msg)) 118 } 119 } 120 }