158 lines
5.1 KiB
Go
158 lines
5.1 KiB
Go
// =============================================================================
|
|
// 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 )
|
|
}
|
|
}
|
|
|