implemented peers communication to send the peersList
arnaucode arnaucode@gmail.com
Fri, 24 Nov 2017 14:23:25 +0100
6 files changed,
181 insertions(+),
36 deletions(-)
M
peer/connections.go
→
peer/connections.go
@@ -1,12 +1,10 @@
package main import ( - "encoding/json" + "bufio" "fmt" "log" "net" - - "github.com/fatih/color" ) func acceptPeers(peer Peer) {@@ -26,7 +24,7 @@ var newPeer Peer
newPeer.IP = getIPFromConn(conn) newPeer.Port = getPortFromConn(conn) newPeer.Conn = conn - listPeers = append(listPeers, newPeer) + peersList.Peers = append(peersList.Peers, newPeer) go handleConn(conn) } }@@ -37,32 +35,38 @@ log.Println("Error connecting to: " + peer.IP + ":" + peer.Port)
return } peer.Conn = conn - listPeers = append(listPeers, peer) + peersList.Peers = append(peersList.Peers, peer) go handleConn(conn) } func handleConn(conn net.Conn) { connRunning := true log.Println("handling conn: " + conn.RemoteAddr().String()) - //reply to the conn - msgB := newMsgBytes("Hi", "New Peer connected") + //reply to the conn, send the peerList + var msg Msg + msg = msg.construct("PeersList", "here my peersList", peersList) + msgB := msg.toBytes() _, err := conn.Write(msgB) - if err != nil { - check(err) - } + check(err) - buffer := make([]byte, 1024) for connRunning { - bytesRead, err := conn.Read(buffer) + /* + buffer := make([]byte, 1024) + bytesRead, err := conn.Read(buffer) + */ + newmsg, err := bufio.NewReader(conn).ReadString('\n') if err != nil { log.Println(err) connRunning = false } else { - s := string(buffer[0:bytesRead]) + /* + fmt.Println(buffer) + fmt.Println(bytesRead) + */ var msg Msg - err := json.Unmarshal([]byte(s), &msg) - check(err) - log.Println("[New msg] [Title]: " + msg.Type + " [Content]: " + msg.Content) - color.Green(msg.Content) + //color.Blue(string(buffer[0:bytesRead])) + //msg = msg.createFromBytes([]byte(string(buffer[0:bytesRead]))) + msg = msg.createFromBytes([]byte(newmsg)) + messageHandler(conn, msg) } } //TODO add that if the peer closed is the p2p server, show a warning message at the peer
M
peer/errors.go
→
peer/errors.go
@@ -1,9 +1,15 @@
package main -import "log" +import ( + "log" + "runtime" +) func check(err error) { if err != nil { + _, fn, line, _ := runtime.Caller(1) + log.Println(line) + log.Println(fn) log.Println(err) } }
M
peer/main.go
→
peer/main.go
@@ -2,35 +2,36 @@ package main
import ( "fmt" + "math/rand" "net" "os" + "strconv" "time" "github.com/fatih/color" ) type Peer struct { - IP string - Port string - Role string //client or server - Conn net.Conn -} -type Msg struct { - Type string `json:"type"` - Content string `json:"content"` + ID string `json:"id"` + IP string `json:"ip"` + Port string `json:"port"` + Role string `json:"role"` //client or server + Conn net.Conn `json:"conn"` } -var listPeers []Peer var running bool +var thisPeerID string func main() { //initialize some vars + rand.Seed(time.Now().Unix()) running = true var peer Peer color.Blue("Starting Peer") readConfig("config.json") + peer.ID = strconv.Itoa(randInt(1, 1000)) //0 is reserved for server peer.IP = config.IP peer.Port = config.Port peer.Role = "client"@@ -41,10 +42,17 @@ if os.Args[1] == "server" {
color.Yellow("Running as p2p server") peer.Role = "server" peer.Port = config.ServerPort - go acceptPeers(peer) + peer.ID = "0" } } + thisPeerID = peer.ID + peersList.PeerID = peer.ID fmt.Println(peer) + peersList.Peers = append(peersList.Peers, peer) + fmt.Println(peersList) + if peer.Role == "server" { + go acceptPeers(peer) + } if peer.Role == "client" { var newPeer Peer newPeer.IP = config.ServerIP
A
peer/messages.go
@@ -0,0 +1,62 @@
+package main + +import ( + "encoding/json" + "fmt" + "log" + "net" + "time" + + "github.com/fatih/color" +) + +type Msg struct { + Type string `json:"type"` + Date time.Time `json:"date"` + Content string `json:"content"` + PeersList PeersList `json:"peerslist"` +} + +func messageHandler(conn net.Conn, msg Msg) { + + log.Println("[New msg]") + log.Println(msg) + + switch msg.Type { + case "Hi": + color.Yellow(msg.Type) + color.Green(msg.Content) + break + case "PeersList": + color.Blue("newPeerslist") + fmt.Println(msg.PeersList) + + time.Sleep(1000 * time.Millisecond) + updatePeersList(conn, msg.PeersList) + propagatePeersList() + printPeersList() + default: + log.Println("Msg.Type not supported") + break + } + +} +func (msg Msg) construct(msgtype string, msgcontent string, peersList PeersList) Msg { + msg.Type = msgtype + msg.Content = msgcontent + msg.PeersList = peersList + msg.Date = time.Now() + return msg +} +func (msg Msg) toBytes() []byte { + msgS, err := json.Marshal(msg) + check(err) + l := string(msgS) + "\n" + r := []byte(l) + return r +} +func (msg Msg) createFromBytes(bytes []byte) Msg { + err := json.Unmarshal(bytes, &msg) + check(err) + return msg +}
A
peer/peersList.go
@@ -0,0 +1,64 @@
+package main + +import ( + "fmt" + "net" + "time" + + "github.com/fatih/color" +) + +type PeersList struct { + PeerID string + Peers []Peer `json:"peerslist"` + Date time.Time `json:"date"` +} + +//var peersList []Peer +var peersList PeersList + +func peerIsInPeersList(p Peer, pl []Peer) int { + r := -1 + for i, peer := range pl { + if peer.IP+":"+peer.Port == p.IP+":"+p.Port { + r = i + } + } + return r +} +func updatePeersList(conn net.Conn, newPeersList PeersList) { + for _, peer := range newPeersList.Peers { + if getIPPortFromConn(conn) == peer.IP+":"+peer.Port { + peer.ID = newPeersList.PeerID + } + i := peerIsInPeersList(peer, peersList.Peers) + if i == -1 { + peersList.Peers = append(peersList.Peers, peer) + } else { + fmt.Println(peersList.Peers[i]) + peersList.Peers[i].ID = peer.ID + } + } +} + +//send the peersList to all the peers except the peer that has send the peersList +func propagatePeersList() { + for _, peer := range peersList.Peers { + if peer.Conn != nil { + var msg Msg + msg = msg.construct("PeersList", "here my peersList", peersList) + msgB := msg.toBytes() + _, err := peer.Conn.Write(msgB) + check(err) + } + } +} +func printPeersList() { + fmt.Println("") + color.Green("PEERSLIST:") + color.Green("thisPeerId: " + thisPeerID) + for _, peer := range peersList.Peers { + fmt.Println(peer) + } + fmt.Println("") +}
M
peer/utils.go
→
peer/utils.go
@@ -1,18 +1,15 @@
package main import ( - "encoding/json" + "math/rand" "net" "strings" ) -func newMsgBytes(msgtype string, msgcontent string) []byte { - var msg Msg - msg.Type = msgtype - msg.Content = msgcontent - msgS, err := json.Marshal(msg) - check(err) - return msgS +func getIPPortFromConn(conn net.Conn) string { + ip := getIPFromConn(conn) + port := getPortFromConn(conn) + return ip + ":" + port } func getIPFromConn(conn net.Conn) string { s := conn.RemoteAddr().String()@@ -26,3 +23,7 @@ s = strings.Split(s, ":")[1]
s = strings.Trim(s, ":") return s } +func randInt(min int, max int) int { + r := rand.Intn(max-min) + min + return r +}