-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.java
239 lines (217 loc) · 9.16 KB
/
server.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
import java.io.*;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class server {
private final int port;
private final int cachePort;
private final String cacheIp;
private final String protocol;
private final ExecutorService executor;
private final CacheManager cacheManager;
public server(int port, String protocol, String cacheIp, int cachePort) throws IOException {
this.port = port;
this.protocol = protocol.toLowerCase();
this.cacheIp = cacheIp;
this.cachePort = cachePort;
this.cacheManager = new CacheManager("server_files");
this.executor = Executors.newCachedThreadPool();
}
public void start() throws IOException {
Files.createDirectories(Paths.get("server_files"));
if ("tcp".equalsIgnoreCase(protocol)) {
startTCPServer();
} else if ("snw".equalsIgnoreCase(protocol)) {
startSNWServer();
} else {
throw new IllegalArgumentException("Unknown protocol: " + protocol);
}
}
private void startTCPServer() throws IOException {
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Server started on port " + port + " using protocol: " + protocol.toUpperCase());
while (true) {
try {
Socket clientSocket = serverSocket.accept();
executor.execute(() -> handleTCPClient(clientSocket));
} catch (IOException e) {
System.err.println("Failed to accept client connection.");
}
}
}
}
private void startSNWServer() {
System.out.println("Server started on port " + port + " using protocol: " + protocol.toUpperCase());
executor.execute(() -> handleSNWClient());
}
private void handleTCPClient(Socket socket) {
try (Transport transport = createTransport(socket)) {
handleClient(transport);
} catch (IOException e) {
System.err.println("Error handling TCP client: " + e.getMessage());
}
}
private void handleSNWClient() {
try (Transport transport = new snw_transport(port)) {
handleClient(transport);
} catch (IOException e) {
System.err.println("Error handling SNW client: " + e.getMessage());
}
}
private void handleClient(Transport transport) throws IOException {
String command;
while ((command = transport.receive()) != null) {
if ("quit".equalsIgnoreCase(command)) {
System.out.println("Client has disconnected.");
break;
} else if (command.startsWith("put ")) {
handlePut(command.substring(4).trim(), transport);
} else if (command.startsWith("get ")) {
handleGet(command.substring(4).trim(), transport);
} else {
transport.send("Unknown command");
System.err.println("Received unknown command: " + command);
}
}
}
private void handlePut(String filename, Transport transport) {
System.out.println("Received PUT request for: " + filename);
try {
transport.send("READY");
String sizeStr = transport.receive();
long fileSize = Long.parseLong(sizeStr);
transport.send("SIZE_RECEIVED");
byte[] data = transport.receiveFile();
Path filePath = Paths.get("server_files", filename);
Files.write(filePath, data);
transport.send("UPLOAD_SUCCESS");
System.out.println("File '" + filename + "' received and saved.");
} catch (IOException | NumberFormatException e) {
System.err.println("Error during file upload: " + e.getMessage());
}
}
private void handleGet(String filename, Transport transport) {
System.out.println("Received GET request for: " + filename);
byte[] data = null;
String deliverySource = null;
data = getFileFromCache(filename);
if (data != null) {
deliverySource = "cache";
System.out.println("File delivered from cache.");
} else {
Path serverFilePath = Paths.get("server_files", filename);
if (Files.exists(serverFilePath)) {
try {
data = Files.readAllBytes(serverFilePath);
deliverySource = "server";
System.out.println("File delivered from server.");
storeFileInCache(filename, data);
} catch (IOException e) {
System.err.println("Error reading file from server.");
}
} else {
System.out.println("File not found on server: " + filename);
}
}
try {
if (data != null) {
transport.send("READY");
transport.send(deliverySource);
transport.sendFile(data);
} else {
transport.send("ERROR: File '" + filename + "' not found on server.");
}
} catch (IOException e) {
System.err.println("Error during file delivery: " + e.getMessage());
}
}
private byte[] getFileFromCache(String filename) {
System.out.println("Attempting to retrieve file from cache: " + filename);
try (Socket cacheSocket = new Socket(cacheIp, cachePort);
DataInputStream dataIn = new DataInputStream(new BufferedInputStream(cacheSocket.getInputStream()));
DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(cacheSocket.getOutputStream()))) {
dataOut.writeUTF("GET " + filename);
dataOut.flush();
String response = dataIn.readUTF();
if ("FOUND".equals(response)) {
int size = dataIn.readInt();
byte[] data = new byte[size];
dataIn.readFully(data);
return data;
} else {
System.out.println("File not found in cache: " + filename);
return null;
}
} catch (IOException e) {
System.err.println("Error communicating with cache service: " + e.getMessage());
return null;
}
}
private void storeFileInCache(String filename, byte[] data) {
System.out.println("Storing file in cache: " + filename);
try (Socket cacheSocket = new Socket(cacheIp, cachePort);
DataInputStream dataIn = new DataInputStream(new BufferedInputStream(cacheSocket.getInputStream()));
DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(cacheSocket.getOutputStream()))) {
dataOut.writeUTF("STORE " + filename);
dataOut.flush();
dataOut.writeInt(data.length);
dataOut.flush();
dataOut.write(data);
dataOut.flush();
String response = dataIn.readUTF();
if ("STORED".equals(response)) {
System.out.println("File '" + filename + "' stored in cache.");
} else {
System.err.println("Failed to store file '" + filename + "' in cache.");
}
} catch (IOException e) {
System.err.println("Error communicating with cache service: " + e.getMessage());
}
}
private Transport createTransport(Socket socket) throws IOException {
switch (protocol) {
case "tcp":
return new tcp_transport(socket);
case "snw":
throw new UnsupportedOperationException("SNW protocol does not use Socket for server");
default:
System.err.println("Unknown protocol: " + protocol);
socket.close();
throw new IllegalArgumentException("Unknown protocol: " + protocol);
}
}
public static void main(String[] args) {
try {
server serverInstance = getServerInstance(args);
serverInstance.start();
} catch (IllegalArgumentException e) {
System.err.println(e.getMessage());
System.out.println("Usage: java server [port] [protocol] [cache ip] [cache port]");
} catch (IOException e) {
System.err.println("IO Exception occurred while starting the server: " + e.getMessage());
System.out.println("Usage: java server [port] [protocol] [cache ip] [cache port]");
}
}
private static server getServerInstance(String[] args) throws IOException {
int port = 10000;
String protocol = "tcp";
String cacheIp = "localhost";
int cachePort = 20000;
if (args.length >= 1) {
port = Integer.parseInt(args[0]);
}
if (args.length >= 2) {
protocol = args[1];
}
if (args.length >= 3) {
cacheIp = args[2];
}
if (args.length >= 4) {
cachePort = Integer.parseInt(args[3]);
}
return new server(port, protocol, cacheIp, cachePort);
}
}