Zappy - Year end project 2
This is a project that Epitech asked us to create in order to allow us to reveiw the notions of the current year.
Loading...
Searching...
No Matches
tcp_server.py
Go to the documentation of this file.
7import sys
8from socket import socket, AF_INET, SOCK_STREAM
9
10from logistics import Logistics
11from convert_data import ConvertData
12from global_variables import GlobalVariables
13from custom_functions import pinfo, psuccess, perror, pdebug, pwarning
14
15
17 """_summary_
18 This is the class in charge of creating a tcp server and connecting to the server binary
19 Args:
20 Thread (_type_): _description_
21 """
22
23 def __init__(self, global_variables: GlobalVariables) -> None:
24 self.global_variables = global_variables
25 self.logistics: Logistics = None
26 self.current_query = ""
27
28 def _process_incoming(self, tcp_socket: socket) -> None:
29 """_summary_
30 Process incoming data from the server binary
31 Args:
32 tcp_socket (socket): _description_: The tcp connection
33 """
34 data = tcp_socket.recv(self.global_variables.server_data.buffer_size)
35 if not data:
36 pinfo(self.global_variables, "No data received")
37 pinfo(self.global_variables, f"Received data: {data.decode()}")
38 if data.decode().lower() in ("exit\n", "dead\n"):
39 pinfo(self.global_variables, "Exit message received")
40 self.global_variables.continue_running = False
41 return
42 translated_data = ConvertData(
43 data,
44 self.global_variables.error,
45 self.global_variables.success
46 )
47 self.logistics.dispatcher(
48 translated_data.to_internal(self.current_query)
49 )
50
51 def _send_output_data(self, tcp_socket: socket) -> bool:
52 """_summary_
53 Send any data that could of been generated by the program
54 Args:
55 tcp_socket (socket): _description_: The tcp connection
56
57 Returns:
58 bool: _description_: if ab error occurred: False, else True
59 """
60 if self.global_variables.response_buffer == []:
61 pdebug(self.global_variables, "Nothing to send")
62 return True
63 data: str = self.global_variables.response_buffer.pop(0)
64 self.current_query = data
65 if (isinstance(data, (str, dict)) is not True) or (isinstance(data, str) and data == ""):
66 pdebug(
68 f"Invalid response type: '{data}'"
69 )
70 return False
71 if isinstance(data, dict):
72 response = ConvertData(
73 data,
74 self.global_variables.error,
75 self.global_variables.success
76 )
77 tcp_socket.sendall((response.to_external()).encode())
78 return True
79 if "\n" != data[-1]:
80 data += "\n"
81 tcp_socket.sendall(data.encode())
82 return True
83
84 def _initialise_logistics(self) -> None:
85 """_summary_
86 This is the function in charge fo
87 Returns:
88 int: _description_
89 """
90 pinfo(self.global_variables, "Initialising logistics")
92 psuccess(self.global_variables, "Logistics initialised")
93
94 def _mainloop(self, tcp_socket: socket) -> int:
95 """_summary_
96 The server loop that is in charge of managing the packets
97
98 Returns:
99 int: _description_
100 """
101 while self.global_variables.continue_running is True:
102 self._process_incoming(tcp_socket)
103 if self.global_variables.continue_running is not True:
104 self._send_output_data(tcp_socket)
105 break
106 if self._send_output_data(tcp_socket) is not True:
107 self.global_variables.current_status = self.global_variables.error
108 return self.global_variables.current_status
109
110 def _start_tcp_socket(self) -> int:
111 """_summary_
112 This is the function that will lay the foundation for the tcp server.
113
114 Returns:
115 int: _description_
116 """
117 status = self.global_variables.success
118 s = socket(AF_INET, SOCK_STREAM)
119 s.connect(
120 (
121 self.global_variables.server_data.ip,
122 self.global_variables.server_data.port
123 )
124 )
125 s.setblocking(self.global_variables.server_data.make_tcp_wait)
126 s.settimeout(self.global_variables.server_data.timeout)
127 pinfo(
128 self.global_variables,
129 self.global_variables.server_data.startup_message
130 )
131 tmp = self._mainloop(s)
132 if tmp != self.global_variables.success:
133 status = tmp
134 return status
135
136 def run(self) -> int:
137 """_summary_
138 This is the function in charge of starting any function that contains the code we wish to run inside the thread we started.
139 """
141 status = self._start_tcp_socket()
142 pwarning(self.global_variables, "The listener is stopping")
143 if status != self.global_variables.success:
144 perror(
145 self.global_variables,
146 f"The listener exited with status: {status}"
147 )
148 return status
149 psuccess(
150 self.global_variables,
151 "The listener exited without any errors"
152 )
153 return self.global_variables.success
154
155
156if __name__ == "__main__":
157 print("This script is not meant to be run as main.")
158 NAME = "my_zappy"
159 IP = "0.0.0.0"
160 PORT = 4242
161 ERROR = 84
162 SUCCESS = 0
163 CLIENT_NUM = 1
164 MAP_X = 20
165 MAP_Y = 20
166 ASCEND = "ASCEND"
167 LEFT = "LEFT"
168 RIGHT = "RIGHT"
169 FORWARD = "FORWARD"
170 LIFE_LENGTH = 200
171 LIFE_INDEX = 0
173 success=0,
174 error=84,
175 ip="0.0.0.0",
176 port=4242,
177 name="my_zappy",
178 debug=True
179 )
180 GI.current_buffer.append(ConvertData("WELCOME").to_internal())
181 TCPSI = TCPServer(GI)
182 TCPSI.start()
183 GI.colourise_output.init_pallet()
184 GI.colourise_error.init_pallet()
185 GI.colourise_output.unload_ressources()
186 sys.exit(GI.current_status)
None _process_incoming(self, socket tcp_socket)
Definition tcp_server.py:28
None __init__(self, GlobalVariables global_variables)
Definition tcp_server.py:23
int _mainloop(self, socket tcp_socket)
Definition tcp_server.py:94
int _start_tcp_socket(self)
None _initialise_logistics(self)
Definition tcp_server.py:84
bool _send_output_data(self, socket tcp_socket)
Definition tcp_server.py:51