Skip to content

Instantly share code, notes, and snippets.

@chischaschos
Created March 6, 2015 03:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chischaschos/6bb44f21ed297d932522 to your computer and use it in GitHub Desktop.
Save chischaschos/6bb44f21ed297d932522 to your computer and use it in GitHub Desktop.
package main
import (
"flag"
"log"
"net"
"strings"
)
var isRoot bool
var startAddress string
var registerAddress string
type Node struct {
MyAddress string
NodeGroup map[string]bool
}
func init() {
flag.BoolVar(&isRoot, "isRoot", false, "by default no server")
flag.StringVar(&startAddress, "startAddress", "localhost:0", "by default no server")
flag.StringVar(&registerAddress, "registerAddress", "", "none")
}
func main() {
flag.Parse()
conn := startNode(startAddress)
defer conn.Close()
node := &Node{}
node.MyAddress = conn.LocalAddr().String()
node.NodeGroup = map[string]bool{}
log.Printf("Started at %s", node.MyAddress)
if registerAddress != "" {
registerToNode(registerAddress, node)
}
listen(conn, node)
}
func startNode(startAddress string) *net.UDPConn {
udpAddr, err := net.ResolveUDPAddr("udp4", startAddress)
if err != nil {
log.Println("can not resolve")
log.Fatal(err)
}
conn, err := net.ListenUDP("udp4", udpAddr)
if err != nil {
log.Println("can not listen")
log.Fatal(err)
}
return conn
}
func listen(conn *net.UDPConn, node *Node) {
var inBytes [1024]byte
for {
n, addr, err := conn.ReadFromUDP(inBytes[:])
if err != nil {
panic(err)
}
if err != nil {
log.Printf("Failed because of %#v\n", err)
return
}
if addr != nil {
log.Println(addr)
log.Println(n)
log.Println(string(inBytes[0:n]))
r := strings.Split(string(inBytes[0:n]), " ")
handleAction(node, r...)
}
}
}
func registerToNode(nodeAddress string, node *Node) {
conn, err := net.Dial("udp", nodeAddress)
if err != nil {
log.Println("can not dial")
panic(err)
}
defer conn.Close()
_, err = conn.Write([]byte("join " + node.MyAddress))
if err != nil {
log.Println("can not write")
panic(err)
}
}
func handleAction(node *Node, message ...string) {
switch message[0] {
case "join":
joinAck(message[1], node)
case "join-ack":
node.NodeGroup[message[1]] = true
log.Println("Current NodeGroup")
log.Println(node.NodeGroup)
}
}
func joinAck(nodeAddress string, node *Node) {
conn, err := net.Dial("udp", nodeAddress)
if err != nil {
log.Println("can not join ack")
panic(err)
}
defer conn.Close()
_, err = conn.Write([]byte("join-ack " + node.MyAddress))
if err != nil {
log.Println("can not write")
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment