server.go
1 // Package that implements the server's side logic of the program 2 package server 3 4 import ( 5 "fmt" 6 "github.com/VasilisBebis/TCP-AM/pkg/messages" 7 "log" 8 "net" 9 "strconv" 10 ) 11 12 // Default Port used if the port is not specified 13 const Def_Port = "12345" 14 15 type Server struct { 16 Listener net.Listener 17 Port string 18 Close bool 19 } 20 21 // NewServer creates a server that will be able to listen on the given port. 22 // By default the server is not opened. To open the server use [OpenServer] 23 func NewServer() *Server { 24 server := Server{Listener: nil, Port: Def_Port, Close: false} 25 return &server 26 } 27 28 // ChangePort changes the TCP port that the server will listen on. 29 func (s *Server) ChangePort(port uint64) { 30 s.Port = strconv.FormatUint(port, 10) 31 } 32 33 // OpenServer opens the listening ability on the TCP port of the given server on all available unicast 34 // and anycast IP addresses of the local system. 35 func (s *Server) OpenServer() { 36 listener, err := net.Listen("tcp", ":"+s.Port) 37 if err != nil { 38 log.Fatal(err) 39 } 40 fmt.Println("Server listening at port " + s.Port) 41 s.Listener = listener 42 43 go func() { 44 for { 45 conn, err := listener.Accept() 46 if err != nil { 47 if s.Close { 48 return 49 } 50 fmt.Println("Connection Error:", err) 51 } 52 go handleClient(conn) 53 } 54 }() 55 } 56 57 func handleClient(c net.Conn) { 58 defer c.Close() 59 fmt.Println("Client: ", c.RemoteAddr(), " connected!") 60 61 buf := make([]byte, 256) 62 _, err := c.Read(buf) 63 if err != nil { 64 log.Println(err) 65 } 66 67 message := messages.DeserializeQuery(buf) 68 header := message.Header 69 op_code := header.Op_code 70 transaction_id := header.Transaction_id 71 72 result, err_code := CalculateResult(op_code, message.Data) 73 var r_ptr *messages.Response 74 if err_code != messages.Ok { 75 r_ptr = messages.NewResponse(err_code, transaction_id, []byte{}) 76 } else { 77 r_ptr = messages.NewResponse(messages.Ok, transaction_id, result) 78 } 79 r := *r_ptr 80 ser_response := r.SerializeResponse() 81 _, err = c.Write(ser_response) 82 if err != nil { 83 log.Println(err) 84 } 85 } 86 87 // CalculateResult calculates the result of the given operation and returns it (or returns an error code if there is any) 88 func CalculateResult(op_code byte, data []byte) (any, byte) { 89 var data_type string 90 91 switch op_code { 92 case 0: 93 data_type = "int8" 94 data, err := messages.DeserializeData(data, data_type) 95 if err != nil { 96 log.Println(err) 97 } 98 raw_data, ok := data.([]int8) 99 if ok { 100 if len(raw_data) < 2 || len(raw_data) > 10 { 101 return nil, messages.ListLengthOutOfBounds 102 } 103 var product int32 104 product = 1 105 for _, v := range raw_data { 106 if v < -5 || v > 5 { 107 return nil, messages.NumberOutOfBounds 108 } 109 product *= int32(v) 110 } 111 return product, messages.Ok 112 } 113 case 1: 114 data_type = "uint8" 115 data, err := messages.DeserializeData(data, data_type) 116 if err != nil { 117 log.Println(err) 118 } 119 raw_data, ok := data.([]uint8) 120 if ok { 121 if len(raw_data) < 2 || len(raw_data) > 20 { 122 return nil, messages.ListLengthOutOfBounds 123 } 124 var sum uint16 125 sum = 0 126 count := 0 127 for _, v := range raw_data { 128 if v > 200 { 129 return nil, messages.NumberOutOfBounds 130 } 131 sum += uint16(v) 132 count++ 133 } 134 avg := float32(sum) / float32(count) 135 return avg, messages.Ok 136 } 137 case 2: 138 data_type = "uint16" 139 data, err := messages.DeserializeData(data, data_type) 140 if err != nil { 141 log.Println(err) 142 } 143 144 raw_data, ok := data.([]uint16) 145 if ok { 146 if len(raw_data) < 4 || len(raw_data) > 20 { 147 return nil, messages.ListLengthOutOfBounds 148 } 149 set_1 := raw_data[:len(raw_data)/2] 150 set_2 := raw_data[len(raw_data)/2:] 151 result := make([]int32, len(raw_data)/2) 152 for i := range len(raw_data) / 2 { 153 if set_1[i] > 60_000 || set_2[i] > 60_000 { 154 return nil, messages.NumberOutOfBounds 155 } 156 result[i] = int32(set_1[i]) - int32(set_2[i]) 157 } 158 return result, messages.Ok 159 } 160 } 161 return nil, messages.InvalidOperation 162 } 163 164 func (s *Server) CloseServer() { 165 s.Close = true 166 err := s.Listener.Close() 167 if err != nil { 168 log.Fatal(err) 169 } 170 fmt.Println("\nServer Closing") 171 }