-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWebServer.java
120 lines (98 loc) · 3.5 KB
/
WebServer.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
import java.net.*;
import java.util.*;
/***
* Web server accepts connections and creates TCP connection that handle each
* request. The threadQueue max size is decided in the config.ini file, and each
* new connection (not new request!) gets a new thread Requests that belong to
* the same IP, go to the thread that is handling this TCP connection
*
* @author ore
*
*/
public class WebServer {
public static int numOfThreads = 0;
// Holds the queue of threads that are dealing with TCP connections
public static HashMap<String, TCPConnection> threadQueue;
public static void main(String argv[]) {
try {
// Establish the listen socket.
ServerSocket socket = new ServerSocket(ConfigUtil.getPort());
System.out.println("Listening on port: " + ConfigUtil.getPort() + ConfigUtil.CRLF);
threadQueue = new HashMap<String, TCPConnection>();
ConfigUtil.init(); // Init the config file
// Process HTTP server requests in an infinite loop.
while (true) {
while (getNumberOfThreads() < ConfigUtil.getMaxThreads()) {
emptyTimedOutConnections();
// Listen for a TCP connection request.
Socket connection = socket.accept();
if (isNewConnection(connection)) {
// Construct an object to process the HTTP request message.
TCPConnection client = new TCPConnection(connection);
String host = connection.getRemoteSocketAddress().toString();
// Create a new thread to process the request.
Thread thread = new Thread(client);
incrementThreadQueue(host, client);
System.out.println("Number of threads running: " + getNumberOfThreads() + ConfigUtil.CRLF);
// Start the thread.
thread.start();
}
}
emptyTimedOutConnections();
}
} catch (Exception e) {
System.err.println("Error Creating server, Corrupt config File: "
+ e);
}
}
/*
* Empties all timed out connections in the server, this is called with
* every new socket that enters the server
*/
private static synchronized void emptyTimedOutConnections() {
for (Map.Entry<String, TCPConnection> entry : threadQueue.entrySet()) {
if (entry.getValue().isThisConnectionTimedOut()) {
entry.getValue().closeConnection();
}
}
}
/*
* Adds this thread (by new socket) to the queue
*/
public static synchronized void incrementThreadQueue(String i_host,
TCPConnection i_connection) {
threadQueue.put(i_host, i_connection);
numOfThreads++;
System.out.println(i_host + " has connected to the server!"
+ ConfigUtil.CRLF);
}
/*
* Dequeues a thread from the queue (this socket) - due to connection time
* out or dead connection
*/
public static synchronized void decrementThreadQueue(String i_host) {
threadQueue.remove(i_host);
numOfThreads--;
}
/*
* Returns the number of threads in the queue (synchronized)
*/
public static synchronized int getNumberOfThreads() {
return numOfThreads;
}
/*
* Returns true if this socket is a new TCP connection (and not another
* request by an old connection
*/
public static synchronized boolean isNewConnection(Socket i_socket) {
String host = i_socket.getRemoteSocketAddress().toString();
return !threadQueue.containsKey(host);
}
/*
* Returns the TCP connection associated with this socket
*/
public static synchronized TCPConnection getConnection(Socket i_socket) {
String host = i_socket.getRemoteSocketAddress().toString();
return threadQueue.get(host);
}
}