Skip to content
Snippets Groups Projects
Commit feaf98f2 authored by owenw2's avatar owenw2
Browse files

working on server-client connection

parent f65a9a5e
No related branches found
No related tags found
No related merge requests found
...@@ -8,10 +8,12 @@ import ( ...@@ -8,10 +8,12 @@ import (
"os" "os"
"strconv" "strconv"
"strings" "strings"
"time"
) )
type Client struct { type Client struct {
Name string // unique identifier for client Name string // unique identifier for client
Timestamp time.Time // timestamp of creation
Connection net.Conn // tcp connection to server Connection net.Conn // tcp connection to server
Connected bool // true if established connection Connected bool // true if established connection
Servers []string // server ip addresses and ports Servers []string // server ip addresses and ports
...@@ -36,6 +38,7 @@ func (client *Client) run_server() { ...@@ -36,6 +38,7 @@ func (client *Client) run_server() {
response := Response{} response := Response{}
dec := gob.NewDecoder(client.Connection) dec := gob.NewDecoder(client.Connection)
dec.Decode(&response) dec.Decode(&response)
fmt.Println("Received result", response.Result, response.Message)
client.ResponseChan <- response client.ResponseChan <- response
} }
} }
...@@ -48,13 +51,17 @@ func (client *Client) connect() { ...@@ -48,13 +51,17 @@ func (client *Client) connect() {
request.Branch = client.Name request.Branch = client.Name
request.Account = client.Name request.Account = client.Name
fmt.Println("Attempting connections")
for _, server := range client.Servers { for _, server := range client.Servers {
fmt.Println("Sending connection request to", server)
connection, err := net.Dial("tcp", server) connection, err := net.Dial("tcp", server)
if err != nil { if err != nil {
fmt.Println("Failed to connect to", server)
continue continue
} }
// send connection request // send begin request
enc := gob.NewEncoder(connection) enc := gob.NewEncoder(connection)
enc.Encode(&request) enc.Encode(&request)
// receive connection response // receive connection response
...@@ -68,6 +75,7 @@ func (client *Client) connect() { ...@@ -68,6 +75,7 @@ func (client *Client) connect() {
return return
} }
} }
fmt.Println("Was not able to connect to any servers")
client.ResponseChan <- response client.ResponseChan <- response
} }
...@@ -99,7 +107,7 @@ func (client *Client) read_file(config_name string) { ...@@ -99,7 +107,7 @@ func (client *Client) read_file(config_name string) {
reader := bufio.NewReader(config) reader := bufio.NewReader(config)
// assumption that only ever have 5 servers (no more, no less) // assumption that only ever have 5 servers (no more, no less)
for i := 0; i < 5; i++ { for i := 0; i < 1; i++ {
text, serr := reader.ReadString('\n') text, serr := reader.ReadString('\n')
substrings := strings.Split(text, " ") substrings := strings.Split(text, " ")
if serr != nil && i < 4 { if serr != nil && i < 4 {
...@@ -119,11 +127,19 @@ func main() { ...@@ -119,11 +127,19 @@ func main() {
// init client // init client
client := Client{ client := Client{
Name: "", Name: "",
Timestamp: time.Time{},
ResponseChan: make(chan Response), ResponseChan: make(chan Response),
} }
clientName := os.Args[0]
configPath := os.Args[2]
// read config and attach server:port // read config and attach server:port
client.read_file("config.txt") client.Name = clientName
client.read_file(configPath)
fmt.Println("Client State:", client.Name, client.Timestamp, client.Connection, client.Connected, client.Servers, len(client.Servers))
reader := bufio.NewReader(os.Stdin) reader := bufio.NewReader(os.Stdin)
// get user inputs // get user inputs
...@@ -131,6 +147,14 @@ func main() { ...@@ -131,6 +147,14 @@ func main() {
input, _ := reader.ReadString('\n') input, _ := reader.ReadString('\n')
substrings := strings.Split(input, " ") substrings := strings.Split(input, " ")
if len(substrings) == 1 {
substrings[0] = strings.ReplaceAll(substrings[0], "\n", "")
} else if len(substrings) == 2 {
substrings[1] = strings.ReplaceAll(substrings[1], "\n", "")
} else if len(substrings) == 3 {
substrings[2] = strings.ReplaceAll(substrings[2], "\n", "")
}
// handle user input // handle user input
if substrings[0] == "BEGIN" { if substrings[0] == "BEGIN" {
// check if connection exists // check if connection exists
...@@ -138,16 +162,18 @@ func main() { ...@@ -138,16 +162,18 @@ func main() {
continue continue
} }
// setup server connection // setup server connection
fmt.Println("HERE")
go client.connect() go client.connect()
response := <-client.ResponseChan response := <-client.ResponseChan
if response.Result { if response.Result {
client.Connected = true client.Connected = true
fmt.Println("OK") client.Timestamp = time.Now()
} else { } else {
fmt.Println("ABORTED") fmt.Println("ABORTED")
return return
} }
} else if substrings[0] == "COMMIT" { } else if substrings[0] == "COMMIT" && client.Connected {
go client.send_request(substrings[0], "", 0) go client.send_request(substrings[0], "", 0)
response := <-client.ResponseChan response := <-client.ResponseChan
if response.Result { if response.Result {
...@@ -157,12 +183,12 @@ func main() { ...@@ -157,12 +183,12 @@ func main() {
fmt.Println("ABORTED") fmt.Println("ABORTED")
return return
} }
} else if substrings[0] == "ABORT" { } else if substrings[0] == "ABORT" && client.Connected {
go client.send_request(substrings[0], "", 0) go client.send_request(substrings[0], "", 0)
<-client.ResponseChan <-client.ResponseChan
fmt.Println("ABORTED") fmt.Println("ABORTED")
return return
} else if substrings[0] == "DEPOSIT" { } else if substrings[0] == "DEPOSIT" && client.Connected {
amount, _ := strconv.Atoi(substrings[2]) amount, _ := strconv.Atoi(substrings[2])
go client.send_request(substrings[0], substrings[1], amount) go client.send_request(substrings[0], substrings[1], amount)
response := <-client.ResponseChan response := <-client.ResponseChan
...@@ -172,7 +198,7 @@ func main() { ...@@ -172,7 +198,7 @@ func main() {
fmt.Println("ABORTED") fmt.Println("ABORTED")
return return
} }
} else if substrings[0] == "BALANCE" { } else if substrings[0] == "BALANCE" && client.Connected {
go client.send_request(substrings[0], substrings[1], 0) go client.send_request(substrings[0], substrings[1], 0)
response := <-client.ResponseChan response := <-client.ResponseChan
if response.Result { if response.Result {
...@@ -181,7 +207,7 @@ func main() { ...@@ -181,7 +207,7 @@ func main() {
fmt.Println("NOT FOUND, ABORTED") fmt.Println("NOT FOUND, ABORTED")
return return
} }
} else if substrings[0] == "WITHDRAW" { } else if substrings[0] == "WITHDRAW" && client.Connected {
amount, _ := strconv.Atoi(substrings[2]) amount, _ := strconv.Atoi(substrings[2])
go client.send_request(substrings[0], substrings[1], amount) go client.send_request(substrings[0], substrings[1], amount)
response := <-client.ResponseChan response := <-client.ResponseChan
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
client : Client/client.go client : Client/client.go
go build -o client Client/client.go go build -o client Client/client.go
server : Server/server.go Server/coordinator.go Server/receiver.go server : Server/server.go
go build -o server Server/server.go Server/coordinator.go Server/receiver.go go build -o server Server/server.go
clean: clean:
rm -f server client rm -f server client
......
package Server
package Server
package Server package main
import (
"bufio"
"encoding/gob"
"fmt"
"net"
"os"
"strings"
"sync"
"time"
)
type Server struct {
BranchName string
Address string
BranchNameToAddress map[string]string
Accounts map[string]*Account
Peers map[string]net.Conn // Connected peers
PeerLock sync.Mutex // Lock for peer map
ClientChan chan Request
// PeerChan chan PeerReque
// ClientListener net.Listener
// PeerListener net.Listener
}
type WriteEntry struct {
Timestamp time.Time
OperationValue int
}
type Account struct {
Name string
Balance int
CreatedBy string
RTS []string
TW map[string]*WriteEntry // tentative writes
WriteTimestampCommitted []time.Time
}
type Request struct {
Transaction string // type of transaction
Branch string
Account string
Amount int
}
type Response struct {
Result bool
Message bool
}
func (server *Server) handle_transaction() {
}
func (server *Server) handle_client(clientConn net.Conn) {
request := Request{}
dec := gob.NewDecoder(clientConn)
dec.Decode(&request)
fmt.Println("Got client message")
}
// listens to tcp netConn from client and then handles (this is only necessary if it is a coordinator server)
func (server *Server) listen_to_clients() {
input, err := net.Listen("tcp", server.Address)
if err != nil {
fmt.Println("Listening on server failed")
}
defer input.Close()
for {
conn, err := input.Accept()
if err != nil {
fmt.Println("Error accepting client connection", err)
continue
}
fmt.Println("Received connection", conn)
go server.handle_client(conn)
}
}
// lsiten to tcp from other servers and handle necessary transactions
func (server *Server) connect_to_peers() {
for address := range server.Peers {
go func(peerAddr string) {
var conn net.Conn
var err error
for {
conn, err = net.Dial("tcp", peerAddr)
if err == nil {
break
}
time.Sleep(2 * time.Second)
}
server.PeerLock.Lock()
server.Peers[peerAddr] = conn
server.PeerLock.Unlock()
fmt.Println("Connected to peer", peerAddr)
// Handle peer communication here if needed
}(address)
}
}
func (server *Server) read_file(config_name string) {
config, error := os.Open(config_name)
if error != nil {
fmt.Println("failed to open config")
return
}
reader := bufio.NewReader(config)
// assumption that only ever have 5 servers (no more, no less)
for i := 0; i < 1; i++ {
text, serr := reader.ReadString('\n')
if serr != nil && i < 4 {
fmt.Println("failed to read config", serr)
}
substrings := strings.Split(text, " ")
// remove new line char from port
substrings[2] = strings.ReplaceAll(substrings[2], "\n", "")
if substrings[0] == server.BranchName {
server.Address = substrings[1] + ":" + substrings[2]
continue
}
// formatteed server address as sp25-cs425-0601.cs.illinois.edu:1234
server.Peers[substrings[1]+":"+substrings[2]] = nil
server.BranchNameToAddress[substrings[0]] = substrings[1] + ":" + substrings[2]
}
config.Close()
}
func main() { func main() {
// init server
server := Server{}
branchName := os.Args[0]
configPath := os.Args[2]
server.BranchName = branchName
server.BranchNameToAddress = make(map[string]string)
server.Accounts = make(map[string]*Account)
server.Peers = make(map[string]net.Conn)
server.read_file(configPath)
fmt.Println("Server State:", server.BranchName, server.Address, server.BranchNameToAddress, server.Accounts, server.Peers)
go server.listen_to_clients()
// go server.connect_to_peers()
for {
continue
}
// timstamped concurrency
// init RTS and TW lists (ordered by timestamp)
//=\
// Strict Timestamp Ordering
} }
File added
...@@ -2,4 +2,14 @@ A sp25-cs425-0601.cs.illinois.edu 1234 ...@@ -2,4 +2,14 @@ A sp25-cs425-0601.cs.illinois.edu 1234
B sp25-cs425-0602.cs.illinois.edu 1234 B sp25-cs425-0602.cs.illinois.edu 1234
C sp25-cs425-0603.cs.illinois.edu 1234 C sp25-cs425-0603.cs.illinois.edu 1234
D sp25-cs425-0604.cs.illinois.edu 1234 D sp25-cs425-0604.cs.illinois.edu 1234
E sp25-cs425-0605.cs.illinois.edu 1234 E sp25-cs425-0605.cs.illinois.edu 1234
\ No newline at end of file
A localhost 1000
B localhost 1001
C localhost 1002
D localhost 1003
E localhost 1004
go run ./Client/client.go abcd config_test.txt
go run ./Server/server.go A config_test.txt
\ No newline at end of file
A sp25-cs425-0601.cs.illinois.edu 1234
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment