init
This commit is contained in:
+6
-7
@@ -1,15 +1,14 @@
|
|||||||
# Binaries for programs and plugins
|
# Binaries for programs and plugins
|
||||||
*.exe
|
node
|
||||||
*.exe~
|
led
|
||||||
*.dll
|
colonel
|
||||||
*.so
|
sentinel
|
||||||
*.dylib
|
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
# Test binary, built with `go test -c`
|
||||||
*.test
|
|
||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
*.out
|
|
||||||
|
|
||||||
# Dependency directories (remove the comment below to include it)
|
# Dependency directories (remove the comment below to include it)
|
||||||
# vendor/
|
# vendor/
|
||||||
|
|
||||||
|
.gitignore
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
all: clean build
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm speak reply
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build speak.go
|
||||||
|
go build reply.go
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# ==============================================================================
|
||||||
|
# Auth: Alex Celani
|
||||||
|
# File: convo.txt
|
||||||
|
# Revn: 05-10-2022 0.1
|
||||||
|
# Func: elaborate on how the convo Golang networks programs should run
|
||||||
|
#
|
||||||
|
# TODO: create
|
||||||
|
# ==============================================================================
|
||||||
|
# CHANGE LOG
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# 05-10-2022: init
|
||||||
|
#
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
uh
|
||||||
|
|
||||||
|
just send a bunch of information back and forth
|
||||||
|
|
||||||
|
A sends data to B, B receives, processes, and responds
|
||||||
|
A receives, processes, and responds
|
||||||
|
|
||||||
|
Repeat until some cutoff condition
|
||||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,84 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: reply.go
|
||||||
|
// Revn: 05-13-2022 0.1
|
||||||
|
// Func: host connection, reply to speak.go
|
||||||
|
//
|
||||||
|
// TODO: create
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-13-2022: init
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func check( err error ) {
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println( "Fatal: ", err.Error() )
|
||||||
|
os.Exit( 1 )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func handle( conn net.Conn ) {
|
||||||
|
|
||||||
|
table := map[string]string{ "hello":"hello",
|
||||||
|
"how are you":"fine and yourself",
|
||||||
|
"well enough for the weather":"aye it scalds",
|
||||||
|
"i lost my begonias":"exit" }
|
||||||
|
var buffer [512]byte
|
||||||
|
for {
|
||||||
|
n, err := conn.Read( buffer[:] )
|
||||||
|
check( err )
|
||||||
|
|
||||||
|
fmt.Println( "\t\t\t", string( buffer[:n] ) )
|
||||||
|
|
||||||
|
time.Sleep( 2 * time.Second )
|
||||||
|
|
||||||
|
response, present := table[string( buffer[:n] )]
|
||||||
|
if present {
|
||||||
|
_, err = conn.Write( []byte( response ) )
|
||||||
|
check( err )
|
||||||
|
|
||||||
|
|
||||||
|
if response == "exit" {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
fmt.Println( response )
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println( "excuse me good sir" )
|
||||||
|
os.Exit( 2 )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
service := ":1200"
|
||||||
|
|
||||||
|
addr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err )
|
||||||
|
|
||||||
|
listener, err := net.ListenTCP( "tcp", addr )
|
||||||
|
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
check( err )
|
||||||
|
|
||||||
|
handle( conn )
|
||||||
|
|
||||||
|
os.Exit( 0 )
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,85 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: speak.go
|
||||||
|
// Revn: 05-11-2022 0.1
|
||||||
|
// Func: initiate conversation
|
||||||
|
//
|
||||||
|
// TODO: create
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-11-2022: init
|
||||||
|
// 05-17-2022: changed an entry in the response table
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func check( err error ) {
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println( "fatal: ", err.Error() )
|
||||||
|
os.Exit( 1 )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func handle( conn net.Conn ) {
|
||||||
|
|
||||||
|
table := map[string]string{ "hello":"how are you",
|
||||||
|
"fine and yourself":"well enough for the weather",
|
||||||
|
"aye it scalds":"i lost my begonias" }
|
||||||
|
var buffer [512]byte
|
||||||
|
for {
|
||||||
|
n, err := conn.Read( buffer[:] )
|
||||||
|
check( err )
|
||||||
|
|
||||||
|
if string( buffer[:n] ) == "exit" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println( "\t\t\t", string( buffer[:n] ) )
|
||||||
|
|
||||||
|
time.Sleep( 2 * time.Second )
|
||||||
|
|
||||||
|
response, present := table[string( buffer[:n] )]
|
||||||
|
if present {
|
||||||
|
_, err = conn.Write( []byte( response ) )
|
||||||
|
check( err )
|
||||||
|
|
||||||
|
fmt.Println( response )
|
||||||
|
} else {
|
||||||
|
fmt.Println( "excuse me good sir" )
|
||||||
|
os.Exit( 2 )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
service := ":1200"
|
||||||
|
|
||||||
|
addr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err )
|
||||||
|
|
||||||
|
conn, err := net.DialTCP( "tcp", nil, addr )
|
||||||
|
check( err )
|
||||||
|
|
||||||
|
_, err = conn.Write( []byte( "hello" ) )
|
||||||
|
check( err )
|
||||||
|
fmt.Println( "hello" )
|
||||||
|
|
||||||
|
handle( conn )
|
||||||
|
|
||||||
|
os.Exit( 0 )
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
all: clean build
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm colonel sentinel node
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build colonel.go
|
||||||
|
go build sentinel.go
|
||||||
|
go build node.go
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: colonel.go
|
||||||
|
// Revn: 06-20-2022 1.0
|
||||||
|
// Func: Send message to another machine and then receive a single
|
||||||
|
// response. Extremely tight bounds, not robust at all
|
||||||
|
//
|
||||||
|
// TODO: comment
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-04-2022: init
|
||||||
|
//*06-20-2022: changed name to reflect first draft of colonel.go
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net" // ResolveTCPAddr, DialTCP, conn.Write,Read
|
||||||
|
"os" // Exit, Stdin, Stderr, Args
|
||||||
|
"fmt" // Println, Print, Fprintf
|
||||||
|
"bufio" // NewScanner, NewScanner.Scan,Text
|
||||||
|
"strings" // ToLower
|
||||||
|
"time" // Now, Sub
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// quick function to take user input
|
||||||
|
func input( ps1 string ) string {
|
||||||
|
fmt.Print( ps1 ) // print prompt
|
||||||
|
scanner := bufio.NewScanner( os.Stdin ) // link to stdin
|
||||||
|
scanner.Scan() // pull data
|
||||||
|
return strings.ToLower( scanner.Text() ) // return lower text
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// quick error checking
|
||||||
|
func check( err error ) {
|
||||||
|
// if user checks an error, it better be nil
|
||||||
|
if err != nil {
|
||||||
|
// put error in string, print in stderr
|
||||||
|
fmt.Fprintf( os.Stderr, "Fatal error: %s", err.Error() )
|
||||||
|
os.Exit( 2 ) // quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// if len is not 2 ( ./name host:port ), print usage and quit
|
||||||
|
if len( os.Args ) != 2 {
|
||||||
|
fmt.Fprintf( os.Stderr, "Usage: %s host:port", os.Args[0] )
|
||||||
|
os.Exit( 1 )
|
||||||
|
}
|
||||||
|
|
||||||
|
service := os.Args[1] // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// "dial" ( establish connection ) to destination ip & port
|
||||||
|
// according to TCP rules
|
||||||
|
// laddr = nil -> local address is localhost
|
||||||
|
conn, err := net.DialTCP( "tcp", nil, tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
var in string = input( ">> " ) // get user input
|
||||||
|
|
||||||
|
start := time.Now() // start round trip timer
|
||||||
|
|
||||||
|
// convert user input to bytes and send over connection
|
||||||
|
_, err = conn.Write( []byte( in ) )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
var buf [512]byte // init byte array
|
||||||
|
// read from connection into byte array
|
||||||
|
// amount of bytes read stored in n
|
||||||
|
//n, err := conn.Read( buf[0:] )
|
||||||
|
n, err := conn.Read( buf[:] )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
t := time.Now() // stop round trip timer
|
||||||
|
|
||||||
|
// convert read bytes into string and print
|
||||||
|
fmt.Println( string( buf[:n] ) )
|
||||||
|
|
||||||
|
fmt.Println() // newline to clean up a little
|
||||||
|
fmt.Println( "rtt: ", t.Sub( start ) ) // print elapsed time
|
||||||
|
|
||||||
|
|
||||||
|
os.Exit( 0 ) // exeunt
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: node.go
|
||||||
|
// Revn: 06-22-2022 1.0
|
||||||
|
// Func: receive data as an endpoint, send response back to middleman
|
||||||
|
//
|
||||||
|
// TODO:
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-04-2022: init
|
||||||
|
// 05-09-2022: began commenting
|
||||||
|
// 05-10-2022: finished commenting
|
||||||
|
// added alter() and forward()
|
||||||
|
// made passed value to alter()/forward() a slice
|
||||||
|
// changed refs to recv byte array to slice of n bytes
|
||||||
|
// 06-20-2022: changed name to reflect first draft of node.go
|
||||||
|
//*06-22-2022: bug squashing and commenting
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net" // ResolveTCPAddr, conn.Write,Read,Close
|
||||||
|
// ListenTCP, listener.Accept
|
||||||
|
"os" // Args, Stderr, Exit
|
||||||
|
"fmt" // Fprintf, Println
|
||||||
|
"strings" // ToLower
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// quick error checking
|
||||||
|
func check( err error ) {
|
||||||
|
// if user checks an error, it better be nil
|
||||||
|
if err != nil {
|
||||||
|
// put error in string, print in stderr
|
||||||
|
fmt.Fprintf( os.Stderr, "Fatal error: %s", err.Error() )
|
||||||
|
os.Exit( 2 ) // quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// parse incoming message, keep only second word
|
||||||
|
func parse( recv string ) string {
|
||||||
|
// split message over spaces
|
||||||
|
keywords := strings.Split( recv, " " )
|
||||||
|
return keywords[1] // return the second word
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to handle incoming connections
|
||||||
|
func handleClient( conn net.Conn ) {
|
||||||
|
defer conn.Close() // barring any error, still close connection
|
||||||
|
|
||||||
|
// init map of fields to their values
|
||||||
|
reply := map[string]string{ "soc" : "30",
|
||||||
|
"batt" : "30",
|
||||||
|
"temp" : "65",
|
||||||
|
"humid" : "35",
|
||||||
|
"sun" : "10",
|
||||||
|
"list" : "soc batt temp humid sun list" }
|
||||||
|
|
||||||
|
var buf [512]byte // declare large byte array, store messages
|
||||||
|
|
||||||
|
// iterate forever to always read over connection
|
||||||
|
for {
|
||||||
|
// read n bytes from connection into buffer
|
||||||
|
n, err := conn.Read( buf[0:] )
|
||||||
|
if err != nil { // erroring on read will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
|
||||||
|
// print recv'd message
|
||||||
|
// string() only works on byte SLICES so [:] is required
|
||||||
|
fmt.Println( "recv: ", string( buf[:n] ) )
|
||||||
|
|
||||||
|
// send input to parse
|
||||||
|
recv := parse( string( buf[:n] ) )
|
||||||
|
fmt.Println( "parse: ", recv ) // print
|
||||||
|
|
||||||
|
// declare variables to grab values from field map
|
||||||
|
var resp string
|
||||||
|
var prs bool
|
||||||
|
// get values from map, prs is false if key (recv) DNE in map
|
||||||
|
resp, prs = reply[recv]
|
||||||
|
if !prs { // if key was not present
|
||||||
|
resp = "field does not exist" // response is DNE
|
||||||
|
}
|
||||||
|
fmt.Println( "answer: ", resp ) // print response
|
||||||
|
|
||||||
|
// write that response back to original client
|
||||||
|
_, err = conn.Write( []byte( resp ) )
|
||||||
|
if err != nil { // erroring on write will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println( "sent: ", resp ) // print response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// ip:port
|
||||||
|
// ip doesn't exist, implies localhost
|
||||||
|
service := ":1202" // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// bind and "listen" to ip and port, according to tcp rules
|
||||||
|
listener, err := net.ListenTCP( "tcp", tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// iterate forever
|
||||||
|
// TODO i mean i can totally make this more user friendly
|
||||||
|
for {
|
||||||
|
// accept a connection that makes its way to bound port
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil { // if connection fails...
|
||||||
|
continue // don't quit program, not fatal error
|
||||||
|
}
|
||||||
|
|
||||||
|
// asynchronous function to handle connection to client
|
||||||
|
go handleClient( conn )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,157 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: sent.go
|
||||||
|
// Revn: 06-22-2022 1.0
|
||||||
|
// Func: Receive message, play with it, send to a third place, receive
|
||||||
|
// response, send off to first place
|
||||||
|
//
|
||||||
|
// TODO: comment
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-04-2022: init
|
||||||
|
// 05-05-2022: commented
|
||||||
|
// 05-10-2022: added argument 'n' to alter() for halving purposes
|
||||||
|
// changed passed value to alter()/forward() a slice
|
||||||
|
// 06-20-2022: changed name to reflect first draft of sentinel.go
|
||||||
|
//*06-22-2022: bug fixing and commenting
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net" // ResolveTCPAddr, DialTCP, conn.Write,Read,Close
|
||||||
|
// ListenTCP, listener.Accept
|
||||||
|
"os" // Exit, Stderr, Stdin, Args
|
||||||
|
"fmt" // Println, Fprintf
|
||||||
|
"strings" // ToLower, ToUpper
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// quick error checking
|
||||||
|
func check( err error ){
|
||||||
|
// if user checks an error, it better be nil
|
||||||
|
if err != nil {
|
||||||
|
// put error in string, print to stderr
|
||||||
|
fmt.Fprintf( os.Stderr, "Fatal error: %s", err.Error() )
|
||||||
|
os.Exit( 1 ) // quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to send message to third party and get response
|
||||||
|
func send( toSend string ) string {
|
||||||
|
// ip:port
|
||||||
|
// ip doesn't exist, implies localhost
|
||||||
|
service := "192.168.1.3:1202" // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// "dial" ( establish connection ) to destination ip & port
|
||||||
|
// according to TCP rules
|
||||||
|
// laddr = nil -> local address is localhost
|
||||||
|
conn, err := net.DialTCP( "tcp", nil, tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
defer conn.Close() // barring any error, still close connection
|
||||||
|
|
||||||
|
// convert user input to bytes and send over connection
|
||||||
|
_, err = conn.Write( []byte( toSend ) )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
var buf [512]byte // init byte array
|
||||||
|
// read from connection into byte array
|
||||||
|
// amount of bytes read stored in n
|
||||||
|
//n, err := conn.Read( buf[0:] )
|
||||||
|
n, err := conn.Read( buf[0:] )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
return string( buf[:n] ) // return only written bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// remove the first word from the string
|
||||||
|
// actually mad inefficient tbh, but it works
|
||||||
|
func parse( recv string ) string {
|
||||||
|
// split string over spaces
|
||||||
|
keywords := strings.Split( recv, " " )
|
||||||
|
var command string // declare return variable
|
||||||
|
// iterate over all but the first word
|
||||||
|
for _, keyword := range keywords[1:] {
|
||||||
|
command = command + keyword // add word to returnable
|
||||||
|
command = command + " " // separate by spaces
|
||||||
|
}
|
||||||
|
// remove the trailing space
|
||||||
|
command = command[:len( command ) - 1]
|
||||||
|
return command // return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to handle incoming connections
|
||||||
|
func handleClient( conn net.Conn ) {
|
||||||
|
defer conn.Close() // barring any error, still close connection
|
||||||
|
|
||||||
|
var buf [512]byte // declare large byte array, store messages
|
||||||
|
|
||||||
|
// iterate forever to always read over connection
|
||||||
|
for {
|
||||||
|
// read n bytes from connection into buffer
|
||||||
|
n, err := conn.Read( buf[0:] )
|
||||||
|
if err != nil { // erroring on read will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
|
||||||
|
// instantiate receipt variable
|
||||||
|
var recv string = string( buf[:n] )
|
||||||
|
|
||||||
|
// print recv'd message
|
||||||
|
// string() only works on byte SLICES so [:] is required
|
||||||
|
fmt.Println( "recv: ", recv )
|
||||||
|
|
||||||
|
// parse the input in some way
|
||||||
|
recv = parse( recv )
|
||||||
|
fmt.Println( "parse: ", recv ) // print parse
|
||||||
|
|
||||||
|
resp := send( recv ) // send message off
|
||||||
|
fmt.Println( "node: ", resp ) // print response
|
||||||
|
|
||||||
|
// write that response back to original client
|
||||||
|
_, err = conn.Write( []byte( resp ) )
|
||||||
|
if err != nil { // erroring on write will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// ip:port
|
||||||
|
// ip doesn't exist, implies localhost
|
||||||
|
service := ":1201" // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// bind and "listen" to ip and port, according to tcp rules
|
||||||
|
listener, err := net.ListenTCP( "tcp", tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// iterate forever
|
||||||
|
// TODO i mean i can totally make this more user friendly
|
||||||
|
for {
|
||||||
|
// accept a connection that makes its way to bound port
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil { // if connection fails...
|
||||||
|
continue // don't quit program, not fatal error
|
||||||
|
}
|
||||||
|
|
||||||
|
// asynchronous function to handle connection to client
|
||||||
|
go handleClient( conn )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: sentinel.go
|
||||||
|
// Revn: 06-22-2022 1.0
|
||||||
|
// Func: Receive message, play with it, send to a third place, receive
|
||||||
|
// response, send off to first place
|
||||||
|
//
|
||||||
|
// TODO: comment
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-04-2022: init
|
||||||
|
// 05-05-2022: commented
|
||||||
|
// 05-10-2022: added argument 'n' to alter() for halving purposes
|
||||||
|
// changed passed value to alter()/forward() a slice
|
||||||
|
// 06-20-2022: changed name to reflect first draft of sentinel.go
|
||||||
|
//*06-22-2022: bug fixing and commenting
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net" // ResolveTCPAddr, DialTCP, conn.Write,Read,Close
|
||||||
|
// ListenTCP, listener.Accept
|
||||||
|
"os" // Exit, Stderr, Stdin, Args
|
||||||
|
"fmt" // Println, Fprintf
|
||||||
|
"strings" // ToLower, ToUpper
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// quick error checking
|
||||||
|
func check( err error ){
|
||||||
|
// if user checks an error, it better be nil
|
||||||
|
if err != nil {
|
||||||
|
// put error in string, print to stderr
|
||||||
|
fmt.Fprintf( os.Stderr, "Fatal error: %s", err.Error() )
|
||||||
|
os.Exit( 1 ) // quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to send message to third party and get response
|
||||||
|
func send( toSend string ) string {
|
||||||
|
// ip:port
|
||||||
|
// ip doesn't exist, implies localhost
|
||||||
|
service := ":1202" // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// "dial" ( establish connection ) to destination ip & port
|
||||||
|
// according to TCP rules
|
||||||
|
// laddr = nil -> local address is localhost
|
||||||
|
conn, err := net.DialTCP( "tcp", nil, tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
defer conn.Close() // barring any error, still close connection
|
||||||
|
|
||||||
|
// convert user input to bytes and send over connection
|
||||||
|
_, err = conn.Write( []byte( toSend ) )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
var buf [512]byte // init byte array
|
||||||
|
// read from connection into byte array
|
||||||
|
// amount of bytes read stored in n
|
||||||
|
//n, err := conn.Read( buf[0:] )
|
||||||
|
n, err := conn.Read( buf[0:] )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
return string( buf[:n] ) // return only written bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// remove the first word from the string
|
||||||
|
// actually mad inefficient tbh, but it works
|
||||||
|
func parse( recv string ) string {
|
||||||
|
// split string over spaces
|
||||||
|
keywords := strings.Split( recv, " " )
|
||||||
|
var command string // declare return variable
|
||||||
|
// iterate over all but the first word
|
||||||
|
for _, keyword := range keywords[1:] {
|
||||||
|
command = command + keyword // add word to returnable
|
||||||
|
command = command + " " // separate by spaces
|
||||||
|
}
|
||||||
|
// remove the trailing space
|
||||||
|
command = command[:len( command ) - 1]
|
||||||
|
return command // return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to handle incoming connections
|
||||||
|
func handleClient( conn net.Conn ) {
|
||||||
|
defer conn.Close() // barring any error, still close connection
|
||||||
|
|
||||||
|
var buf [512]byte // declare large byte array, store messages
|
||||||
|
|
||||||
|
// iterate forever to always read over connection
|
||||||
|
for {
|
||||||
|
// read n bytes from connection into buffer
|
||||||
|
n, err := conn.Read( buf[0:] )
|
||||||
|
if err != nil { // erroring on read will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
|
||||||
|
// instantiate receipt variable
|
||||||
|
var recv string = string( buf[:n] )
|
||||||
|
|
||||||
|
// print recv'd message
|
||||||
|
// string() only works on byte SLICES so [:] is required
|
||||||
|
fmt.Println( "recv: ", recv )
|
||||||
|
|
||||||
|
// parse the input in some way
|
||||||
|
recv = parse( recv )
|
||||||
|
fmt.Println( "parse: ", recv ) // print parse
|
||||||
|
|
||||||
|
resp := send( recv ) // send message off
|
||||||
|
fmt.Println( "node: ", resp ) // print response
|
||||||
|
|
||||||
|
// write that response back to original client
|
||||||
|
_, err = conn.Write( []byte( resp ) )
|
||||||
|
if err != nil { // erroring on write will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// ip:port
|
||||||
|
// ip doesn't exist, implies localhost
|
||||||
|
service := ":1201" // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// bind and "listen" to ip and port, according to tcp rules
|
||||||
|
listener, err := net.ListenTCP( "tcp", tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// iterate forever
|
||||||
|
// TODO i mean i can totally make this more user friendly
|
||||||
|
for {
|
||||||
|
// accept a connection that makes its way to bound port
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil { // if connection fails...
|
||||||
|
continue // don't quit program, not fatal error
|
||||||
|
}
|
||||||
|
|
||||||
|
// asynchronous function to handle connection to client
|
||||||
|
go handleClient( conn )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
all: clean build
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm colonel sentinel
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build colonel.go
|
||||||
|
go build sentinel.go
|
||||||
|
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: colonel.go
|
||||||
|
// Revn: 06-22-2022 1.0
|
||||||
|
// Func: Send message to another machine and then receive a single
|
||||||
|
// response
|
||||||
|
//
|
||||||
|
// TODO: comment
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-04-2022: init
|
||||||
|
// 06-20-2022: changed name to reflect first draft of colonel.go
|
||||||
|
//*06-22-2022: bug fixing and commenting
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net" // ResolveTCPAddr, DialTCP, conn.Write,Read
|
||||||
|
"os" // Exit, Stdin, Stderr, Args
|
||||||
|
"fmt" // Println, Print, Fprintf
|
||||||
|
"bufio" // NewScanner, NewScanner.Scan,Text
|
||||||
|
"strings" // ToLower
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// quick function to take user input
|
||||||
|
func input( ps1 string ) string {
|
||||||
|
fmt.Print( ps1 ) // print prompt
|
||||||
|
scanner := bufio.NewScanner( os.Stdin ) // link to stdin
|
||||||
|
scanner.Scan() // pull data
|
||||||
|
return strings.ToLower( scanner.Text() ) // return lower text
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// quick error checking
|
||||||
|
func check( err error ) {
|
||||||
|
// if user checks an error, it better be nil
|
||||||
|
if err != nil {
|
||||||
|
// put error in string, print in stderr
|
||||||
|
fmt.Fprintf( os.Stderr, "Fatal error: %s", err.Error() )
|
||||||
|
os.Exit( 2 ) // quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// if len is not 2 ( ./name host:port ), print usage and quit
|
||||||
|
if len( os.Args ) != 2 {
|
||||||
|
fmt.Fprintf( os.Stderr, "Usage: %s host:port", os.Args[0] )
|
||||||
|
os.Exit( 1 )
|
||||||
|
}
|
||||||
|
|
||||||
|
service := os.Args[1] // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// "dial" ( establish connection ) to destination ip & port
|
||||||
|
// according to TCP rules
|
||||||
|
// laddr = nil -> local address is localhost
|
||||||
|
conn, err := net.DialTCP( "tcp", nil, tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
var in string = input( ">> " ) // get user input
|
||||||
|
|
||||||
|
// convert user input to bytes and send over connection
|
||||||
|
_, err = conn.Write( []byte( in ) )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
os.Exit( 0 ) // exeunt
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: sentinel.go
|
||||||
|
// Revn: 06-22-2022 1.0
|
||||||
|
// Func: Receive message, play with it, send to a third place, receive
|
||||||
|
// response, send off to first place
|
||||||
|
//
|
||||||
|
// TODO: comment
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-04-2022: init
|
||||||
|
// 05-05-2022: commented
|
||||||
|
// 05-10-2022: added argument 'n' to alter() for halving purposes
|
||||||
|
// changed passed value to alter()/forward() a slice
|
||||||
|
// 06-20-2022: changed name to reflect first draft of sentinel.go
|
||||||
|
//*06-22-2022: bug fixing and comments
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net" // ResolveTCPAddr, DialTCP, conn.Write,Read,Close
|
||||||
|
// ListenTCP, listener.Accept
|
||||||
|
"os" // Exit, Stderr, Stdin, Args
|
||||||
|
"fmt" // Println, Fprintf
|
||||||
|
"github.com/stianeikeland/go-rpio" // talk to RasPi pins
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// quick error checking
|
||||||
|
func check( err error ){
|
||||||
|
// if user checks an error, it better be nil
|
||||||
|
if err != nil {
|
||||||
|
// put error in string, print to stderr
|
||||||
|
fmt.Fprintf( os.Stderr, "Fatal error: %s", err.Error() )
|
||||||
|
os.Exit( 1 ) // quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to handle incoming connections
|
||||||
|
func handleClient( conn net.Conn ) {
|
||||||
|
defer conn.Close() // barring any error, still close connection
|
||||||
|
|
||||||
|
var buf [512]byte // declare large byte array, store messages
|
||||||
|
|
||||||
|
// iterate forever to always read over connection
|
||||||
|
for {
|
||||||
|
// read n bytes from connection into buffer
|
||||||
|
n, err := conn.Read( buf[0:] )
|
||||||
|
if err != nil { // erroring on read will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
|
||||||
|
// instantiate receipt variable
|
||||||
|
var recv string = string( buf[:n] )
|
||||||
|
|
||||||
|
// print recv'd message
|
||||||
|
// string() only works on byte SLICES so [:] is required
|
||||||
|
fmt.Println( "recv: ", recv )
|
||||||
|
|
||||||
|
// toggle pin on successful receipt
|
||||||
|
pin.Toggle()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// declare pin
|
||||||
|
var (
|
||||||
|
// Use mcu pin 10, corresponds to physical pin 19 on the pi
|
||||||
|
pin = rpio.Pin(10)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// Open and map memory to access gpio, check for errors
|
||||||
|
// inline open gpio pin and check the error var
|
||||||
|
if err := rpio.Open(); err != nil {
|
||||||
|
// on error, print error and exit
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmap gpio memory when done
|
||||||
|
defer rpio.Close()
|
||||||
|
|
||||||
|
// Set pin to output mode
|
||||||
|
pin.Output()
|
||||||
|
|
||||||
|
// ip:port
|
||||||
|
// ip doesn't exist, implies localhost
|
||||||
|
service := ":1201" // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// bind and "listen" to ip and port, according to tcp rules
|
||||||
|
listener, err := net.ListenTCP( "tcp", tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// iterate forever
|
||||||
|
// TODO i mean i can totally make this more user friendly
|
||||||
|
for {
|
||||||
|
// accept a connection that makes its way to bound port
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil { // if connection fails...
|
||||||
|
continue // don't quit program, not fatal error
|
||||||
|
}
|
||||||
|
|
||||||
|
// asynchronous function to handle connection to client
|
||||||
|
go handleClient( conn )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
all: clean build
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm colonel sentinel led
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build colonel.go
|
||||||
|
go build sentinel.go
|
||||||
|
go build led.go
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: boot.go
|
||||||
|
// Revn: 06-23-2022 0.1
|
||||||
|
// Func: Blink a light when the pi boots (or on login, but who cares)
|
||||||
|
//
|
||||||
|
// TODO: create
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 06-23-2022: init
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stianeikeland/go-rpio"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Toggles a LED on physical pin 19 (mcu pin 10)
|
||||||
|
Connect a LED with resistor from pin 19 to ground.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Use mcu pin 10, corresponds to physical pin 19 on the pi
|
||||||
|
var pin rpio.Pin
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
pin = rpio.Pin( 10 )
|
||||||
|
// Open and map memory to access gpio, check for errors
|
||||||
|
if err := rpio.Open(); err != nil {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmap gpio memory when done
|
||||||
|
defer rpio.Close()
|
||||||
|
|
||||||
|
// Set pin to output mode
|
||||||
|
pin.Output()
|
||||||
|
|
||||||
|
// Toggle pin 20 times
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
pin.Toggle()
|
||||||
|
time.Sleep(time.Second / 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: colonel.go
|
||||||
|
// Revn: 06-23-2022 1.1
|
||||||
|
// Func: Send message to another machine and then receive a single
|
||||||
|
// response. Extremely tight bounds, not robust at all
|
||||||
|
//
|
||||||
|
// TODO: comment
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-04-2022: init
|
||||||
|
//*06-20-2022: changed name to reflect first draft of colonel.go
|
||||||
|
// 06-23-2022: made input an infinite loop
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net" // ResolveTCPAddr, DialTCP, conn.Write,Read
|
||||||
|
"os" // Exit, Stdin, Stderr, Args
|
||||||
|
"fmt" // Println, Print, Fprintf
|
||||||
|
"bufio" // NewScanner, NewScanner.Scan,Text
|
||||||
|
"strings" // ToLower
|
||||||
|
"time" // Now, Sub
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// quick function to take user input
|
||||||
|
func input( ps1 string ) string {
|
||||||
|
fmt.Print( ps1 ) // print prompt
|
||||||
|
scanner := bufio.NewScanner( os.Stdin ) // link to stdin
|
||||||
|
scanner.Scan() // pull data
|
||||||
|
return strings.ToLower( scanner.Text() ) // return lower text
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// quick error checking
|
||||||
|
func check( err error ) {
|
||||||
|
// if user checks an error, it better be nil
|
||||||
|
if err != nil {
|
||||||
|
// put error in string, print in stderr
|
||||||
|
fmt.Fprintf( os.Stderr, "Fatal error: %s", err.Error() )
|
||||||
|
os.Exit( 2 ) // quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// if len is not 2 ( ./name host:port ), print usage and quit
|
||||||
|
if len( os.Args ) != 2 {
|
||||||
|
fmt.Fprintf( os.Stderr, "Usage: %s host:port", os.Args[0] )
|
||||||
|
os.Exit( 1 )
|
||||||
|
}
|
||||||
|
|
||||||
|
service := os.Args[1] // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// "dial" ( establish connection ) to destination ip & port
|
||||||
|
// according to TCP rules
|
||||||
|
// laddr = nil -> local address is localhost
|
||||||
|
conn, err := net.DialTCP( "tcp", nil, tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
for { // loop forever
|
||||||
|
|
||||||
|
var in string = input( ">> " ) // get user input
|
||||||
|
|
||||||
|
start := time.Now() // start round trip timer
|
||||||
|
|
||||||
|
// convert user input to bytes and send over connection
|
||||||
|
_, err = conn.Write( []byte( in ) )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
var buf [512]byte // init byte array
|
||||||
|
// read from connection into byte array
|
||||||
|
// amount of bytes read stored in n
|
||||||
|
//n, err := conn.Read( buf[0:] )
|
||||||
|
n, err := conn.Read( buf[:] )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
t := time.Now() // stop round trip timer
|
||||||
|
|
||||||
|
// convert read bytes into string and print
|
||||||
|
fmt.Println( "<<", string( buf[:n] ) )
|
||||||
|
|
||||||
|
fmt.Println() // newline to clean up a little
|
||||||
|
fmt.Println( "rtt: ", t.Sub( start ) ) // print time
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Exit( 0 ) // exeunt
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
color;blue green red purple teal yellow white
|
||||||
|
status;on off
|
||||||
|
&&
|
||||||
|
color;blue
|
||||||
|
status;off
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# ==============================================================================
|
||||||
|
# Auth: Alex Celani
|
||||||
|
# File: XXX.xx
|
||||||
|
# Revn: MM-DD-YYYY 0.0
|
||||||
|
# Func:
|
||||||
|
#
|
||||||
|
# TODO: create
|
||||||
|
# ==============================================================================
|
||||||
|
# CHANGE LOG
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# MM-DD-YYYY: init
|
||||||
|
#
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
literally
|
||||||
|
combine draft1 with draft2
|
||||||
|
|
||||||
|
sentinel:: your whole job, tbh, is to forward to the correct node
|
||||||
|
and there's really only one node
|
||||||
|
change stuff like "plant humid" into "plant.humid" or
|
||||||
|
"lamp color" into "lamp.color"
|
||||||
|
|
||||||
|
node:: move real parsing here
|
||||||
|
control RBG common anode led
|
||||||
|
node name -> led
|
||||||
|
fields ->^v led.color
|
||||||
|
^ on
|
||||||
|
^ off
|
||||||
|
v status
|
||||||
|
^v bright
|
||||||
|
v list
|
||||||
|
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: led.go
|
||||||
|
// Revn: 06-26-2022 1.2
|
||||||
|
// Func: receive data as an endpoint, send response back to middleman
|
||||||
|
//
|
||||||
|
// TODO:
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-04-2022: init
|
||||||
|
// 05-09-2022: began commenting
|
||||||
|
// 05-10-2022: finished commenting
|
||||||
|
// added alter() and forward()
|
||||||
|
// made passed value to alter()/forward() a slice
|
||||||
|
// changed refs to recv byte array to slice of n bytes
|
||||||
|
// 06-20-2022: changed name to reflect first draft of node.go
|
||||||
|
//*06-22-2022: bug squashing and commenting
|
||||||
|
// 06-23-2022: updated to produce three different colors
|
||||||
|
// 06-26-2022: commented
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net" // ResolveTCPAddr, conn.Write,Read,Close
|
||||||
|
// ListenTCP, listener.Accept
|
||||||
|
"os" // Args, Stderr, Exit
|
||||||
|
"fmt" // Fprintf, Println
|
||||||
|
"strings" // ToLower
|
||||||
|
"github.com/stianeikeland/go-rpio" // talk to RasPi pins
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// quick error checking
|
||||||
|
func check( err error ) {
|
||||||
|
// if user checks an error, it better be nil
|
||||||
|
if err != nil {
|
||||||
|
// put error in string, print in stderr
|
||||||
|
fmt.Fprintf( os.Stderr, "Fatal error: %s", err.Error() )
|
||||||
|
os.Exit( 2 ) // quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// parse incoming message, keep only second word
|
||||||
|
func parse( recv string ) string {
|
||||||
|
// split message over spaces
|
||||||
|
keywords := strings.Split( recv, " " )
|
||||||
|
return keywords[1] // return the second word
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to handle incoming connections
|
||||||
|
func handleClient( conn net.Conn ) {
|
||||||
|
defer conn.Close() // barring any error, still close connection
|
||||||
|
|
||||||
|
var buf [512]byte // declare large byte array, store messages
|
||||||
|
|
||||||
|
// iterate forever to always read over connection
|
||||||
|
for {
|
||||||
|
// read n bytes from connection into buffer
|
||||||
|
n, err := conn.Read( buf[0:] )
|
||||||
|
if err != nil { // erroring on read will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
|
||||||
|
// print recv'd message
|
||||||
|
// string() only works on byte SLICES so [:] is required
|
||||||
|
fmt.Println( "recv: ", string( buf[:n] ) )
|
||||||
|
|
||||||
|
// split command into words for ease of parsing
|
||||||
|
command := strings.Split( string( buf[:n] ), " " )
|
||||||
|
|
||||||
|
if command[1] != "led" { // confirm message belongs here
|
||||||
|
os.Exit( 2 ) // if not, exit
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp string // declare response variable
|
||||||
|
|
||||||
|
|
||||||
|
// TODO convert to switches?
|
||||||
|
// len is 3 for "asK" commands
|
||||||
|
if len( command ) == 3 {
|
||||||
|
if command[2] == "color" {
|
||||||
|
// if user wants color, return color
|
||||||
|
resp = color
|
||||||
|
} else if command[2] == "status" {
|
||||||
|
// if user wants status, return status
|
||||||
|
resp = status
|
||||||
|
} else {
|
||||||
|
// there are only those two fields
|
||||||
|
resp = "usage unknown"
|
||||||
|
}
|
||||||
|
// len is 4 for tell commands
|
||||||
|
} else if len( command ) == 4 {
|
||||||
|
// if user wants to set color
|
||||||
|
if command[2] == "color" {
|
||||||
|
color = command[3] // set current color
|
||||||
|
resp = color // return current color
|
||||||
|
switch color {
|
||||||
|
case "blue": // does user want blue?
|
||||||
|
// turn blue on, turn rest off
|
||||||
|
pinB.High()
|
||||||
|
pinR.Low()
|
||||||
|
pinG.Low()
|
||||||
|
case "red": // does user want red?
|
||||||
|
// turn red on, turn rest off
|
||||||
|
pinB.Low()
|
||||||
|
pinR.High()
|
||||||
|
pinG.Low()
|
||||||
|
case "green": // does user want green?
|
||||||
|
// turn green on, turn rest off
|
||||||
|
pinB.Low()
|
||||||
|
pinR.Low()
|
||||||
|
pinG.High()
|
||||||
|
default: // color unknown
|
||||||
|
// turn off
|
||||||
|
pinB.Low()
|
||||||
|
pinR.Low()
|
||||||
|
pinG.Low()
|
||||||
|
}
|
||||||
|
// if user wants to set status
|
||||||
|
} else if command[2] == "status" {
|
||||||
|
status = command[3] // set current status
|
||||||
|
resp = status // return current status
|
||||||
|
switch status {
|
||||||
|
case "on": // does user want on?
|
||||||
|
// default to red
|
||||||
|
pinB.Low()
|
||||||
|
pinR.High()
|
||||||
|
pinG.Low()
|
||||||
|
default: // anything else, like off
|
||||||
|
// default to off
|
||||||
|
pinB.Low()
|
||||||
|
pinR.Low()
|
||||||
|
pinG.Low()
|
||||||
|
}
|
||||||
|
// user entered something else entirely
|
||||||
|
} else {
|
||||||
|
resp = "usage unknown"
|
||||||
|
}
|
||||||
|
// no other lengths are valid
|
||||||
|
} else {
|
||||||
|
os.Exit( 2 ) // exit in this case
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println( "answer: ", resp ) // print response
|
||||||
|
|
||||||
|
// write that response back to original client
|
||||||
|
_, err = conn.Write( []byte( resp ) )
|
||||||
|
if err != nil { // erroring on write will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println( "sent: ", resp ) // print response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//var params = make( map[string]string )
|
||||||
|
//var states = make( map[string]string )
|
||||||
|
var pinR rpio.Pin // declare red led pin
|
||||||
|
var pinG rpio.Pin // declare green led pin
|
||||||
|
var pinB rpio.Pin // declare blue led pin
|
||||||
|
var color string // declare color variable
|
||||||
|
var status string // declare status variable
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// initialize pins to GPIO 11, 9, and 25
|
||||||
|
pinR = rpio.Pin( 11 )
|
||||||
|
pinG = rpio.Pin( 9 )
|
||||||
|
pinB = rpio.Pin( 25 )
|
||||||
|
|
||||||
|
if err := rpio.Open(); err != nil {
|
||||||
|
// on error, print error and exit
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmap gpio memory when done
|
||||||
|
defer rpio.Close()
|
||||||
|
|
||||||
|
// Set pins to output mode
|
||||||
|
pinR.Output()
|
||||||
|
pinG.Output()
|
||||||
|
pinB.Output()
|
||||||
|
|
||||||
|
// ip:port
|
||||||
|
// ip doesn't exist, implies localhost
|
||||||
|
service := ":1202" // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// bind and "listen" to ip and port, according to tcp rules
|
||||||
|
listener, err := net.ListenTCP( "tcp", tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// iterate forever
|
||||||
|
// TODO i mean i can totally make this more user friendly
|
||||||
|
for {
|
||||||
|
// accept a connection that makes its way to bound port
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil { // if connection fails...
|
||||||
|
continue // don't quit program, not fatal error
|
||||||
|
}
|
||||||
|
|
||||||
|
// asynchronous function to handle connection to client
|
||||||
|
go handleClient( conn )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: sentinel.go
|
||||||
|
// Revn: 06-26-2022 1.2
|
||||||
|
// Func: Receive message, determine recipient, forward, get response,
|
||||||
|
// forward back
|
||||||
|
//
|
||||||
|
// TODO:
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-04-2022: init
|
||||||
|
// 05-05-2022: commented
|
||||||
|
// 05-10-2022: added argument 'n' to alter() for halving purposes
|
||||||
|
// changed passed value to alter()/forward() a slice
|
||||||
|
// 06-20-2022: changed name to reflect first draft of sentinel.go
|
||||||
|
//*06-22-2022: bug fixing and commenting
|
||||||
|
// 06-23-2022: removed call to parse
|
||||||
|
// 06-26-2022: refined a new route() function to check for destination
|
||||||
|
// validity
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net" // ResolveTCPAddr, DialTCP, conn.Write,Read,Close
|
||||||
|
// ListenTCP, listener.Accept
|
||||||
|
"os" // Exit, Stderr, Stdin, Args
|
||||||
|
"fmt" // Println, Fprintf
|
||||||
|
"strings" // ToLower, ToUpper
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// quick error checking
|
||||||
|
func check( err error ){
|
||||||
|
// if user checks an error, it better be nil
|
||||||
|
if err != nil {
|
||||||
|
// put error in string, print to stderr
|
||||||
|
fmt.Fprintf( os.Stderr, "Fatal error: %s", err.Error() )
|
||||||
|
os.Exit( 1 ) // quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// read the given message and route to the right endpoint
|
||||||
|
func route( recv []string ) bool {
|
||||||
|
return recv[1] == "led" // only option right now is led
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to send message to third party and get response
|
||||||
|
func send( toSend string ) string {
|
||||||
|
// ip:port
|
||||||
|
// ip doesn't exist, implies localhost
|
||||||
|
service := ":1202" // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// "dial" ( establish connection ) to destination ip & port
|
||||||
|
// according to TCP rules
|
||||||
|
// laddr = nil -> local address is localhost
|
||||||
|
conn, err := net.DialTCP( "tcp", nil, tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
defer conn.Close() // barring any error, still close connection
|
||||||
|
|
||||||
|
// convert user input to bytes and send over connection
|
||||||
|
_, err = conn.Write( []byte( toSend ) )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
var buf [512]byte // init byte array
|
||||||
|
// read from connection into byte array
|
||||||
|
// amount of bytes read stored in n
|
||||||
|
//n, err := conn.Read( buf[0:] )
|
||||||
|
n, err := conn.Read( buf[0:] )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
return string( buf[:n] ) // return only written bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to handle incoming connections
|
||||||
|
func handleClient( conn net.Conn ) {
|
||||||
|
defer conn.Close() // barring any error, still close connection
|
||||||
|
|
||||||
|
var buf [512]byte // declare large byte array, store messages
|
||||||
|
|
||||||
|
// iterate forever to always read over connection
|
||||||
|
for {
|
||||||
|
// read n bytes from connection into buffer
|
||||||
|
n, err := conn.Read( buf[0:] )
|
||||||
|
if err != nil { // erroring on read will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
|
||||||
|
// instantiate receipt variable
|
||||||
|
var recv string = string( buf[:n] )
|
||||||
|
|
||||||
|
// print recv'd message
|
||||||
|
// string() only works on byte SLICES so [:] is required
|
||||||
|
fmt.Println( "recv: ", recv )
|
||||||
|
|
||||||
|
keywords := strings.Split( recv, " " )
|
||||||
|
|
||||||
|
// parse the input in some way
|
||||||
|
var resp string // declare response variable
|
||||||
|
if route( keywords ) { // is destination valid?
|
||||||
|
resp = send( recv ) // send message and get response
|
||||||
|
// if user wants a list of endpoints
|
||||||
|
} else if keywords[1] == "list" {
|
||||||
|
resp = "led" // return list of endpoints
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fmt.Println( "node: ", resp ) // print response
|
||||||
|
|
||||||
|
// write that response back to original client
|
||||||
|
_, err = conn.Write( []byte( resp ) )
|
||||||
|
if err != nil { // erroring on write will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// ip:port
|
||||||
|
// ip doesn't exist, implies localhost
|
||||||
|
service := ":1201" // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// bind and "listen" to ip and port, according to tcp rules
|
||||||
|
listener, err := net.ListenTCP( "tcp", tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// iterate forever
|
||||||
|
// TODO i mean i can totally make this more user friendly
|
||||||
|
for {
|
||||||
|
// accept a connection that makes its way to bound port
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil { // if connection fails...
|
||||||
|
continue // don't quit program, not fatal error
|
||||||
|
}
|
||||||
|
|
||||||
|
// asynchronous function to handle connection to client
|
||||||
|
go handleClient( conn )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+136
@@ -0,0 +1,136 @@
|
|||||||
|
# ====================================================================
|
||||||
|
# Auth: dodd
|
||||||
|
# File: sentinel.txt
|
||||||
|
# Revn: 05-10-2022 0.2
|
||||||
|
# Func: jot down some ideas about what the hub is and how it works
|
||||||
|
#
|
||||||
|
# TODO:
|
||||||
|
# ====================================================================
|
||||||
|
# CHANGE LOG
|
||||||
|
# --------------------------------------------------------------------
|
||||||
|
# 04-27-2022: init
|
||||||
|
# 05-10-2022: changed name from hub to sentinel
|
||||||
|
#
|
||||||
|
# ====================================================================
|
||||||
|
|
||||||
|
|
||||||
|
elevator pitch:: execute a command in terminal
|
||||||
|
terminal sends request to external hub device
|
||||||
|
hub pings one or more homemade smarthome devices
|
||||||
|
smarthome devices repond to hub
|
||||||
|
hub sends information back to terminal
|
||||||
|
terminal displays requested data
|
||||||
|
|
||||||
|
idea:: filter network model
|
||||||
|
"
|
||||||
|
/----\ /----\
|
||||||
|
/ v / v
|
||||||
|
|A| |B| |C| ( but with more C nodes )
|
||||||
|
^ / ^ /
|
||||||
|
\----/ \----/
|
||||||
|
"
|
||||||
|
|
||||||
|
terminal program is node A
|
||||||
|
hub is node B
|
||||||
|
other devices are nodes C
|
||||||
|
cat feeder
|
||||||
|
ball lamp
|
||||||
|
door monitor
|
||||||
|
etc
|
||||||
|
|
||||||
|
design::
|
||||||
|
how -> networking language
|
||||||
|
_python_ --> easy to write, will work
|
||||||
|
moves challenge to the project
|
||||||
|
_c/c++_ --> segmentation fault (core dumped). pass
|
||||||
|
_golang_ --> will need to learn networks pretty well
|
||||||
|
I'm already getting pretty good experience
|
||||||
|
with golang tho
|
||||||
|
_rust_ --> can't even get the fucking syntax to highlight
|
||||||
|
|
||||||
|
everything important is going to need to be hardcoded? ports,
|
||||||
|
ip addresses
|
||||||
|
|
||||||
|
probably would want to be connection-oriented protocol
|
||||||
|
TCP/IP
|
||||||
|
|
||||||
|
|
||||||
|
usage:: terminal commands
|
||||||
|
ask:: -> ask deviceC property
|
||||||
|
==> send message to deviceC asking for status report
|
||||||
|
on property
|
||||||
|
==> fail gracefully if property doesnt exist for given
|
||||||
|
device
|
||||||
|
--> ask cat-feeder fill example command
|
||||||
|
--> cat-feeder.fill 50% example response
|
||||||
|
|
||||||
|
--> ask ball-lamp soc example command
|
||||||
|
--> ball-lamp.soc 20% example response
|
||||||
|
|
||||||
|
tell:: -> tell deviceC command argument
|
||||||
|
==> send message to deviceC instructing it to commit
|
||||||
|
an action
|
||||||
|
==> fail gracefully if command doesn't exist for
|
||||||
|
device or if argument is invalid
|
||||||
|
|
||||||
|
--> tell door arm on example command
|
||||||
|
--> door.arm on example response
|
||||||
|
|
||||||
|
--> tell ball-lamp color blue example command
|
||||||
|
--> ball-lamp.color blue example response
|
||||||
|
|
||||||
|
list:: -> list [deviceC] -v
|
||||||
|
==> return a list of devices (deviceC not specified)
|
||||||
|
==> ping deviceC to see what properties it has and
|
||||||
|
their direction
|
||||||
|
==> including verbose -v flag shows devices and their
|
||||||
|
properties
|
||||||
|
==> including -v and a device is treated like only
|
||||||
|
specifying the device
|
||||||
|
|
||||||
|
--> list example command
|
||||||
|
--> door example response
|
||||||
|
ball-lamp
|
||||||
|
cat-feeder
|
||||||
|
office-light
|
||||||
|
|
||||||
|
--> list ball-lamp example command
|
||||||
|
--> ball-lamp example response
|
||||||
|
\--^ on
|
||||||
|
\--^ off
|
||||||
|
\--^ color
|
||||||
|
\-- white
|
||||||
|
\-- red
|
||||||
|
\-- green
|
||||||
|
\-- blue
|
||||||
|
\-- rainbow
|
||||||
|
\--^ bright[ness]
|
||||||
|
\-- [1 - 100]
|
||||||
|
\--v soc
|
||||||
|
\--v batt[ery]
|
||||||
|
|
||||||
|
--> list -v example command
|
||||||
|
--> door example response
|
||||||
|
\--^ arm
|
||||||
|
\--v status
|
||||||
|
\--v soc
|
||||||
|
\--v batt[ery]
|
||||||
|
ball-lamp
|
||||||
|
\--^ on
|
||||||
|
\--^ off
|
||||||
|
\--^ color
|
||||||
|
\-- white
|
||||||
|
\-- red
|
||||||
|
\-- green
|
||||||
|
\-- blue
|
||||||
|
\-- rainbow
|
||||||
|
\--^ bright[ness]
|
||||||
|
\-- [1 - 100]
|
||||||
|
\--v soc
|
||||||
|
\--v batt[ery]
|
||||||
|
(etc)
|
||||||
|
|
||||||
|
stats:: -> stats
|
||||||
|
==> request statistics from all online devices
|
||||||
|
===> uptime, battery, current status on all
|
||||||
|
properties, en masse
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
all: clean build
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm messagerA messagerB messagerC
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build messagerA.go
|
||||||
|
go build messagerB.go
|
||||||
|
go build messagerC.go
|
||||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,95 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: messagerA.go
|
||||||
|
// Revn: 05-04-2022 0.1
|
||||||
|
// Func: Send message to another machine and then receive a single
|
||||||
|
// response
|
||||||
|
//
|
||||||
|
// TODO: comment
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-04-2022: init
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net" // ResolveTCPAddr, DialTCP, conn.Write,Read
|
||||||
|
"os" // Exit, Stdin, Stderr, Args
|
||||||
|
"fmt" // Println, Print, Fprintf
|
||||||
|
"bufio" // NewScanner, NewScanner.Scan,Text
|
||||||
|
"strings" // ToLower
|
||||||
|
"time" // Now, Sub
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// quick function to take user input
|
||||||
|
func input( ps1 string ) string {
|
||||||
|
fmt.Print( ps1 ) // print prompt
|
||||||
|
scanner := bufio.NewScanner( os.Stdin ) // link to stdin
|
||||||
|
scanner.Scan() // pull data
|
||||||
|
return strings.ToLower( scanner.Text() ) // return lower text
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// quick error checking
|
||||||
|
func check( err error ) {
|
||||||
|
// if user checks an error, it better be nil
|
||||||
|
if err != nil {
|
||||||
|
// put error in string, print in stderr
|
||||||
|
fmt.Fprintf( os.Stderr, "Fatal error: %s", err.Error() )
|
||||||
|
os.Exit( 2 ) // quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// if len is not 2 ( ./name host:port ), print usage and quit
|
||||||
|
if len( os.Args ) != 2 {
|
||||||
|
fmt.Fprintf( os.Stderr, "Usage: %s host:port", os.Args[0] )
|
||||||
|
os.Exit( 1 )
|
||||||
|
}
|
||||||
|
|
||||||
|
service := os.Args[1] // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// "dial" ( establish connection ) to destination ip & port
|
||||||
|
// according to TCP rules
|
||||||
|
// laddr = nil -> local address is localhost
|
||||||
|
conn, err := net.DialTCP( "tcp", nil, tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
var in string = input( ">> " ) // get user input
|
||||||
|
|
||||||
|
start := time.Now() // start round trip timer
|
||||||
|
|
||||||
|
// convert user input to bytes and send over connection
|
||||||
|
_, err = conn.Write( []byte( in ) )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
var buf [512]byte // init byte array
|
||||||
|
// read from connection into byte array
|
||||||
|
// amount of bytes read stored in n
|
||||||
|
//n, err := conn.Read( buf[0:] )
|
||||||
|
n, err := conn.Read( buf[:] )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
t := time.Now() // stop round trip timer
|
||||||
|
|
||||||
|
// convert read bytes into string and print
|
||||||
|
fmt.Println( string( buf[:n] ) )
|
||||||
|
|
||||||
|
fmt.Println() // newline to clean up a little
|
||||||
|
fmt.Println( "rtt: ", t.Sub( start ) ) // print elapsed time
|
||||||
|
|
||||||
|
|
||||||
|
os.Exit( 0 ) // exeunt
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,151 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: messagerB.go
|
||||||
|
// Revn: 05-10-2022 0.3
|
||||||
|
// Func: Receive message, play with it, send to a third place, receive
|
||||||
|
// response, send off to first place
|
||||||
|
//
|
||||||
|
// TODO: comment
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-04-2022: init
|
||||||
|
// 05-05-2022: commented
|
||||||
|
// 05-10-2022: added argument 'n' to alter() for halving purposes
|
||||||
|
// changed passed value to alter()/forward() a slice
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net" // ResolveTCPAddr, DialTCP, conn.Write,Read,Close
|
||||||
|
// ListenTCP, listener.Accept
|
||||||
|
"os" // Exit, Stderr, Stdin, Args
|
||||||
|
"fmt" // Println, Fprintf
|
||||||
|
"strings" // ToLower, ToUpper
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// quick error checking
|
||||||
|
func check( err error ){
|
||||||
|
// if user checks an error, it better be nil
|
||||||
|
if err != nil {
|
||||||
|
// put error in string, print to stderr
|
||||||
|
fmt.Fprintf( os.Stderr, "Fatal error: %s", err.Error() )
|
||||||
|
os.Exit( 1 ) // quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to send message to third party and get response
|
||||||
|
func quickSend( send string ) string {
|
||||||
|
// ip:port
|
||||||
|
// ip doesn't exist, implies localhost
|
||||||
|
service := ":1202" // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// "dial" ( establish connection ) to destination ip & port
|
||||||
|
// according to TCP rules
|
||||||
|
// laddr = nil -> local address is localhost
|
||||||
|
conn, err := net.DialTCP( "tcp", nil, tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
defer conn.Close() // barring any error, still close connection
|
||||||
|
|
||||||
|
// convert user input to bytes and send over connection
|
||||||
|
_, err = conn.Write( []byte( send ) )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
var buf [512]byte // init byte array
|
||||||
|
// read from connection into byte array
|
||||||
|
// amount of bytes read stored in n
|
||||||
|
//n, err := conn.Read( buf[0:] )
|
||||||
|
n, err := conn.Read( buf[0:] )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
return string( buf[:n] ) // return only written bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to change received message before passing it along
|
||||||
|
func alter( recv []byte, n int ) string {
|
||||||
|
var send string = string( recv[:n/2] )
|
||||||
|
send = strings.ToUpper( send )
|
||||||
|
fmt.Println( "to c: ", send )
|
||||||
|
return send
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to convert message to string before forwarding
|
||||||
|
func forward( recv []byte ) string {
|
||||||
|
return string( recv[:] )
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to handle incoming connections
|
||||||
|
func handleClient( conn net.Conn ) {
|
||||||
|
defer conn.Close() // barring any error, still close connection
|
||||||
|
|
||||||
|
var buf [512]byte // declare large byte array, store messages
|
||||||
|
|
||||||
|
// iterate forever to always read over connection
|
||||||
|
for {
|
||||||
|
// read n bytes from connection into buffer
|
||||||
|
n, err := conn.Read( buf[0:] )
|
||||||
|
if err != nil { // erroring on read will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
|
||||||
|
// print recv'd message
|
||||||
|
// string() only works on byte SLICES so [:] is required
|
||||||
|
fmt.Println( "recv: ", string( buf[:] ) )
|
||||||
|
|
||||||
|
// var send string = string( buf[:n/2] )
|
||||||
|
// send = strings.ToUpper( send )
|
||||||
|
|
||||||
|
send := alter( buf[:], n ) // send message to get changed
|
||||||
|
// send := forward( buf[:] )
|
||||||
|
recv := quickSend( send ) // send message off
|
||||||
|
fmt.Println( "из c: ", recv ) // print response
|
||||||
|
|
||||||
|
// write that response back to original client
|
||||||
|
_, err = conn.Write( []byte( recv ) )
|
||||||
|
if err != nil { // erroring on write will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// ip:port
|
||||||
|
// ip doesn't exist, implies localhost
|
||||||
|
service := ":1201" // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// bind and "listen" to ip and port, according to tcp rules
|
||||||
|
listener, err := net.ListenTCP( "tcp", tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// iterate forever
|
||||||
|
// TODO i mean i can totally make this more user friendly
|
||||||
|
for {
|
||||||
|
// accept a connection that makes its way to bound port
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil { // if connection fails...
|
||||||
|
continue // don't quit program, not fatal error
|
||||||
|
}
|
||||||
|
|
||||||
|
// asynchronous function to handle connection to client
|
||||||
|
go handleClient( conn )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,118 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Auth: Alex Celani
|
||||||
|
// File: messagerC.go
|
||||||
|
// Revn: 05-10-2022 0.3
|
||||||
|
// Func:
|
||||||
|
//
|
||||||
|
// TODO: create
|
||||||
|
// =============================================================================
|
||||||
|
// CHANGE LOG
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 05-04-2022: init
|
||||||
|
// 05-09-2022: began commenting
|
||||||
|
// 05-10-2022: finished commenting
|
||||||
|
// added alter() and forward()
|
||||||
|
// made passed value to alter()/forward() a slice
|
||||||
|
// changed refs to recv byte array to slice of n bytes
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net" // ResolveTCPAddr, conn.Write,Read,Close
|
||||||
|
// ListenTCP, listener.Accept
|
||||||
|
"os" // Args, Stderr, Exit
|
||||||
|
"fmt" // Fprintf, Println
|
||||||
|
"strings" // ToLower
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// quick error checking
|
||||||
|
func check( err error ) {
|
||||||
|
// if user checks an error, it better be nil
|
||||||
|
if err != nil {
|
||||||
|
// put error in string, print in stderr
|
||||||
|
fmt.Fprintf( os.Stderr, "Fatal error: %s", err.Error() )
|
||||||
|
os.Exit( 2 ) // quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to change received message before passing it along
|
||||||
|
func alter( recv []byte ) string {
|
||||||
|
var send string = string( recv[:] )
|
||||||
|
send = send + " " + send
|
||||||
|
send = strings.ToLower( send )
|
||||||
|
return send
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to convert message to string before forwarding
|
||||||
|
func forward( recv []byte ) string {
|
||||||
|
return string( recv[:] )
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to handle incoming connections
|
||||||
|
func handleClient( conn net.Conn ) {
|
||||||
|
defer conn.Close() // barring any error, still close connection
|
||||||
|
|
||||||
|
var buf [512]byte // declare large byte array, store messages
|
||||||
|
|
||||||
|
// iterate forever to always read over connection
|
||||||
|
for {
|
||||||
|
// read n bytes from connection into buffer
|
||||||
|
n, err := conn.Read( buf[0:] )
|
||||||
|
if err != nil { // erroring on read will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
|
||||||
|
// print recv'd message
|
||||||
|
// string() only works on byte SLICES so [:] is required
|
||||||
|
fmt.Println( "recv: ", string( buf[:n] ) )
|
||||||
|
|
||||||
|
send := alter( buf[:n] ) // send message ot get changed
|
||||||
|
// send := forward( buf[:] )
|
||||||
|
|
||||||
|
// write that response back to original client
|
||||||
|
_, err = conn.Write( []byte( send ) )
|
||||||
|
if err != nil { // erroring on write will simply leave the
|
||||||
|
return // function so it can start again later
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println( "sent: ", send ) // print response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// ip:port
|
||||||
|
// ip doesn't exist, implies localhost
|
||||||
|
service := ":1202" // capture ip address and host
|
||||||
|
|
||||||
|
// "resolve" ip & host according to TCP rules
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr( "tcp", service )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// bind and "listen" to ip and port, according to tcp rules
|
||||||
|
listener, err := net.ListenTCP( "tcp", tcpAddr )
|
||||||
|
check( err ) // check error
|
||||||
|
|
||||||
|
// iterate forever
|
||||||
|
// TODO i mean i can totally make this more user friendly
|
||||||
|
for {
|
||||||
|
// accept a connection that makes its way to bound port
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil { // if connection fails...
|
||||||
|
continue // don't quit program, not fatal error
|
||||||
|
}
|
||||||
|
|
||||||
|
// asynchronous function to handle connection to client
|
||||||
|
go handleClient( conn )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user