/ pkg / server / server.go
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  }