From 278b8e1a7359872feeb78857f6166a8a0ca8375a Mon Sep 17 00:00:00 2001 From: afonso Date: Wed, 17 Apr 2024 14:09:42 +0100 Subject: [PATCH] [PD1] Generic networking server and client implemented --- Projs/PD1/cmd/server/server.go | 2 +- Projs/PD1/internal/protocol/protocol.go | 28 +++---- Projs/PD1/internal/server/server.go | 47 +++++++----- .../internal/utils/networking/networking.go | 75 ++++++++++++++++++- 4 files changed, 114 insertions(+), 38 deletions(-) diff --git a/Projs/PD1/cmd/server/server.go b/Projs/PD1/cmd/server/server.go index c93ba9b..0526a10 100644 --- a/Projs/PD1/cmd/server/server.go +++ b/Projs/PD1/cmd/server/server.go @@ -5,5 +5,5 @@ import ( ) func main(){ - server.Run() + server.Run(8080) } diff --git a/Projs/PD1/internal/protocol/protocol.go b/Projs/PD1/internal/protocol/protocol.go index bc407e5..bb6d636 100644 --- a/Projs/PD1/internal/protocol/protocol.go +++ b/Projs/PD1/internal/protocol/protocol.go @@ -1,8 +1,6 @@ package protocol import ( - "encoding/json" - "fmt" "time" ) @@ -12,8 +10,9 @@ const ( ReqPK PacketType = iota ReqAllMsg ReqMsg + SubmitMsg SendPK - UsrMsg + Msg ) type PacketBody interface {} @@ -39,18 +38,19 @@ type RequestMsg struct { Num uint16 } -// Server --> Client: Send the client the requested public key -type SendPubKey struct { - Key []byte -} - -// Bidirectional: Send messages between server and clients -type SendMessage struct { +// Client --> Server: Send message from client to server +type SubmitMessage struct { ToUID string Subject []byte Body []byte } +// Server --> Client: Send the client the requested public key +type SendPubKey struct { + Key []byte +} + +// Server --> Client: Send the client a message type Message struct { FromUID string ToUID string @@ -58,11 +58,3 @@ type Message struct { Body []byte Timestamp time.Time } - -func (p Packet) Marshal() ([]byte, error) { - return json.Marshal(p) -} - -func (p *Packet) Unmarshal(data []byte) error { - return json.Unmarshal(data, p) -} diff --git a/Projs/PD1/internal/server/server.go b/Projs/PD1/internal/server/server.go index a176564..53b37fe 100644 --- a/Projs/PD1/internal/server/server.go +++ b/Projs/PD1/internal/server/server.go @@ -1,30 +1,43 @@ package server import ( - _ "PD1/internal/utils/cryptoUtils" - _ "PD1/internal/utils/networking" + "PD1/internal/protocol" + "PD1/internal/utils/networking" + "encoding/json" "fmt" - "net" ) -func clientHandler(conn net.Conn) { +func clientHandler(connection networking.Connection[protocol.Packet]) { + defer connection.Conn.Close() + + jd := json.NewDecoder(connection.Conn) + + for { + var pac protocol.Packet + jd.Decode(&pac) + + switch pac.Flag { + case protocol.ReqPK: + fmt.Println("ReqPK") + case protocol.ReqAllMsg: + fmt.Println("ReqAllMsg") + case protocol.ReqMsg: + fmt.Println("ReqMsg") + case protocol.SubmitMsg: + fmt.Println("SubmitMsh") + } + } } func Run(port int) { - ip, err := net.ResolveTCPAddr("tcp", ":8080") - if err != nil { - panic("Server could not bind to address") - } - listener, err := net.ListenTCP("tcp", ip) - if err != nil { - panic("Server could not listen on address") - } + server := networking.NewServer[protocol.Packet](port) + go server.ListenLoop() + for { - conn, err := listener.Accept() - if err!=nil{ - panic("Server could not accept connection") - } - go clientHandler(conn) + //Receive connection via channel + conn := <-server.C + //Launch client handler via clientHandler + go clientHandler(conn) } } diff --git a/Projs/PD1/internal/utils/networking/networking.go b/Projs/PD1/internal/utils/networking/networking.go index 33cdced..e4caa88 100644 --- a/Projs/PD1/internal/utils/networking/networking.go +++ b/Projs/PD1/internal/utils/networking/networking.go @@ -1,5 +1,76 @@ package networking -func sendPacket(){ - +import ( + "encoding/json" + "fmt" + "net" +) + +type Server[T any] struct { + listener net.Listener + C chan Connection[T] +} + +type Client[T any] struct { + conn net.Conn +} + +type Connection[T any] struct { + Conn net.Conn + encoder *json.Encoder + decoder *json.Decoder +} + +func NewServer[T any](port int) Server[T]{ + + listener, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", port)) + if err != nil { + panic("Server could not bind to address") + } + return Server[T]{ + listener:listener, + C: make(chan Connection[T]), + } +} + +func (s *Server[T]) ListenLoop() { + + for { + listenerConn, err := s.listener.Accept() + if err != nil { + panic("Server could not accept connection") + } + conn := NewConnection[T](listenerConn) + s.C <- conn + } +} + +func (c Client[T]) Connect() Connection[T] { + dialConn, err := net.Dial("tcp", "localhost:8080") + if err != nil { + panic("Could not open connection to server") + } + return NewConnection[T](dialConn) +} + +func NewConnection[T any](netConn net.Conn) Connection[T] { + return Connection[T]{ + Conn: netConn, + encoder: json.NewEncoder(netConn), + decoder: json.NewDecoder(netConn), + } +} + +func (jc Connection[T]) Send(obj T) { + if err := jc.encoder.Encode(&obj); err != nil { + panic("Failed encoding data or sending it to connection") + } +} + +func (jc Connection[T]) Receive() T { + var obj T + if err := jc.decoder.Decode(&obj); err != nil { + panic("Failed decoding data or reading it from connection") + } + return obj }