mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-13 11:23:40 +00:00
examples: add classic network snake test example
Adding this example to test multiple concurrent socket connections.
This commit is contained in:
committed by
deadprogram
parent
e7931c6a22
commit
aa7bd47c68
@@ -0,0 +1,30 @@
|
|||||||
|
//go:build ninafw || wioterminal
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/netlink"
|
||||||
|
"tinygo.org/x/drivers/netlink/probe"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ssid string
|
||||||
|
pass string
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
|
||||||
|
link, _ := probe.Probe()
|
||||||
|
|
||||||
|
err := link.NetConnect(&netlink.ConnectParams{
|
||||||
|
Ssid: ssid,
|
||||||
|
Passphrase: pass,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
// This example is the classic snake network test. The snake is feed a steady
|
||||||
|
// diet of pkts and the pkts work themselves thru the snake segments and exit
|
||||||
|
// the tail. Each snake segment is a TCP socket connection to a server. The
|
||||||
|
// server echos pkts received back to the snake, and serves each segment on a
|
||||||
|
// different port. (See server/main.go for server).
|
||||||
|
//
|
||||||
|
// snake | server
|
||||||
|
// |
|
||||||
|
// head ----->---|-->--+
|
||||||
|
// seg a | |
|
||||||
|
// +---<-|--<--+
|
||||||
|
// | |
|
||||||
|
// +-->--|-->--+
|
||||||
|
// seg b | |
|
||||||
|
// +---<-|--<--+
|
||||||
|
// | |
|
||||||
|
// +-->--|-->--+
|
||||||
|
// seg c | |
|
||||||
|
// +---<-|--<--+
|
||||||
|
// | |
|
||||||
|
// +-->--|-->--+
|
||||||
|
// ... | |
|
||||||
|
// +---<-|--<--+
|
||||||
|
// | |
|
||||||
|
// +-->--|-->--+
|
||||||
|
// seg n | |
|
||||||
|
// tail -------<-|--<--+
|
||||||
|
// |
|
||||||
|
|
||||||
|
// The snake segments are linked by channels and each segment is run as a go
|
||||||
|
// func. This forces segments to connect and run concurrently, which is a good
|
||||||
|
// test of the underlying driver's ability to handle concurrent connections.
|
||||||
|
|
||||||
|
//go:build ninafw || wioterminal
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed main.go
|
||||||
|
var code string
|
||||||
|
|
||||||
|
var (
|
||||||
|
server string = "10.0.0.100:8080"
|
||||||
|
)
|
||||||
|
|
||||||
|
func segment(in chan []byte, out chan []byte) {
|
||||||
|
var buf [512]byte
|
||||||
|
for {
|
||||||
|
c, err := net.Dial("tcp", server)
|
||||||
|
for ; err != nil; c, err = net.Dial("tcp", server) {
|
||||||
|
println(err.Error())
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case msg := <-in:
|
||||||
|
_, err := c.Write(msg)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
n, err := c.Read(buf[:])
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
out <- buf[:n]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func feedit(head chan []byte) {
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
head <- []byte(fmt.Sprintf("\n---%d---\n", i))
|
||||||
|
for _, line := range strings.Split(code, "\n") {
|
||||||
|
if len(line) == 0 {
|
||||||
|
line = " "
|
||||||
|
}
|
||||||
|
head <- []byte(line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var head = make(chan []byte)
|
||||||
|
var a = make(chan []byte)
|
||||||
|
var b = make(chan []byte)
|
||||||
|
var c = make(chan []byte)
|
||||||
|
var d = make(chan []byte)
|
||||||
|
var e = make(chan []byte)
|
||||||
|
var f = make(chan []byte)
|
||||||
|
var tail = make(chan []byte)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// The snake
|
||||||
|
go segment(head, a)
|
||||||
|
go segment(a, b)
|
||||||
|
go segment(b, c)
|
||||||
|
go segment(c, d)
|
||||||
|
go segment(d, e)
|
||||||
|
go segment(e, f)
|
||||||
|
go segment(f, tail)
|
||||||
|
|
||||||
|
go feedit(head)
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case msg := <-tail:
|
||||||
|
println(string(msg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Listen for connections
|
||||||
|
l, err := net.Listen("tcp", ":8080")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
defer l.Close()
|
||||||
|
println("Listening on port", ":8080")
|
||||||
|
for {
|
||||||
|
// Wait for a connection
|
||||||
|
conn, err := l.Accept()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
println("Accepted connection from", conn.RemoteAddr().String())
|
||||||
|
// Service the new connection in a goroutine.
|
||||||
|
// The loop then returns to accepting, so that
|
||||||
|
// multiple connections may be served concurrently
|
||||||
|
go func(c net.Conn) {
|
||||||
|
// Echo all incoming data
|
||||||
|
io.Copy(c, c)
|
||||||
|
// Shut down the connection
|
||||||
|
c.Close()
|
||||||
|
}(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user