Skip to content

Commit 210cdcb

Browse files
committedApr 24, 2017
removed old files, added final versions of.java files -- done
1 parent 5665aab commit 210cdcb

24 files changed

+169
-3569
lines changed
 

‎EchoServer.class

-2.6 KB
Binary file not shown.

‎EchoServer.java

-35
This file was deleted.

‎Test1.class

-11.2 KB
Binary file not shown.

‎Test1.java

-605
This file was deleted.

‎clientThread.class

-14.3 KB
Binary file not shown.

‎clientThread.java

+23-21
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//package ce325.hw2;
2+
13
import java.net.*;
24
import java.io.*;
35
import java.util.concurrent.*;
@@ -33,7 +35,7 @@ public void run(){
3335
remoteAd= curReq.remoteAd;
3436
out=curReq.outStream;
3537
data=curReq.dataStream;
36-
38+
System.out.println(Thread.currentThread().getName()+" ->req : "+request+"\n");
3739
//various declarations
3840
String readFile;
3941
String codeStatus;
@@ -79,19 +81,7 @@ else if (parts[2].equals("HTTP/1.0") ){
7981

8082
//Creates file object for the currently asked file
8183
File filepath= new File (mainServer.ROOT + parts[1]);
82-
83-
//example:get the ".mp3" extension part from a file if it is "AmyWinehouse.mp3"
84-
try{
85-
int index = parts[1].lastIndexOf('.');
86-
extensionForMime= parts[1].substring(index);
87-
}catch (Exception Ex){
88-
StringWriter sw = new StringWriter();
89-
Ex.printStackTrace(new PrintWriter(sw));
90-
String exceptionAsString = sw.toString();
91-
writeErrorLog(reqLog,exceptionAsString,remoteAd);
92-
}
93-
94-
84+
9585
/*Use info to check for protocol errors*/
9686

9787
/*
@@ -101,6 +91,7 @@ else if (parts[2].equals("HTTP/1.0") ){
10191
if(!parts[0].equals("GET")){
10292
codeStatus = "405 Method Not Allowed";
10393
writeAccessLog(reqLog,userStr,codeStatus);
94+
System.out.println("405 error written in log \n");
10495
responseForError(codeStatus,out);
10596
}
10697
/*
@@ -110,14 +101,16 @@ else if (parts[2].equals("HTTP/1.0") ){
110101
else if(!filepath.exists()){
111102
codeStatus = "404 File Not Found";
112103
writeAccessLog(reqLog,userStr,codeStatus);
104+
System.out.println("404 error written in log \n");
113105
responseForError(codeStatus,out);
114106
}
115107
/*
116108
ERROR 400 Bad Request
117109
*/
118110
else if((parts[2]== null ) ||( !(parts[2].equals("HTTP/1.1")) && !(parts[2].equals("HTTP/1.0")) ) ){
119111
codeStatus = "400 Bad Request";
120-
writeAccessLog(reqLog,userStr,codeStatus);
112+
writeAccessLog(reqLog,userStr,codeStatus);
113+
System.out.println("400 error written in log \n");
121114
responseForError(codeStatus,out);
122115
}
123116
//else 200 OK ,proceeds to send response
@@ -138,9 +131,21 @@ else if((parts[2]== null ) ||( !(parts[2].equals("HTTP/1.1")) && !(parts[2].equa
138131
writeErrorLog(reqLog,exceptionAsString,remoteAd);
139132
}
140133

141-
synchronized (this){
134+
synchronized (this){ //remove it
135+
142136
// if it is a FILE, write to acces log and then send it
143137
if (filepath.isFile() ) {
138+
//example:get the ".mp3" extension part from a file if it is "AmyWinehouse.mp3"
139+
try{
140+
int index = parts[1].lastIndexOf('.');
141+
extensionForMime= parts[1].substring(index);
142+
}catch (Exception Ex){
143+
StringWriter sw = new StringWriter();
144+
Ex.printStackTrace(new PrintWriter(sw));
145+
String exceptionAsString = sw.toString();
146+
writeErrorLog(reqLog,exceptionAsString,remoteAd);
147+
}
148+
144149
writeAccessLog(reqLog,userStr,codeStatus);
145150
sendFile( versionOfHttp, out, filepath, extensionForMime, data);
146151
}
@@ -169,12 +174,8 @@ else if (filepath.isDirectory() ) {
169174
}
170175
else {//else, show the existing directory -> sendDirectory
171176
try {
172-
173177
writeAccessLog(reqLog,userStr,codeStatus);
174178
sendDirectory(filepath,out);
175-
176-
177-
178179
}
179180
catch (Exception E){
180181
StringWriter sw = new StringWriter();
@@ -200,7 +201,7 @@ else if (filepath.isDirectory() ) {
200201

201202
writeErrorLog(reqLog,exceptionAsString,remoteAd);
202203
writeAccessLog(reqLog,userStr,codeStatus);
203-
204+
System.out.println("500 error written in log \n");
204205
responseForError(codeStatus,out);
205206
}
206207

@@ -513,6 +514,7 @@ synchronized public static void sendDirectory(File filepath, PrintWriter out) th
513514
html.append( "<td valign=\"top\"><a href=\""+extensionForLocalHost+"\">"+file.getName()+"</a></td> ");
514515
html.append( "<td valign=\"top\">"+(file.isDirectory() ? "- " : getFileSize(file) )+"</td>");
515516
html.append( "<td valign=\"top\">"+getLastModifiedDate(file.lastModified())+"</td> </tr>\r\n ");
517+
counterF=counterF-1;
516518
}
517519

518520

‎icons/favicon.ico

318 Bytes
Binary file not shown.

‎logs.class

-14.1 KB
Binary file not shown.

‎logs.java

-798
This file was deleted.

‎mainServer.class

-4.33 KB
Binary file not shown.

‎mainServer.java

+56-20
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//package ce325.hw2;
2+
13
import java.net.*;
24
import java.io.*;
35
import java.util.concurrent.*;
@@ -7,25 +9,27 @@
79
import java.nio.file.Files;
810

911

12+
1013
public class mainServer{
1114

1215
//public variables/fields for other classes and concurrency
1316

14-
/*declare here variables that will be taken from xml for server "initialization"*/
17+
//declare variables that will be taken from xml for server "initialization"
1518
public static String SERVERNAME = "CE325 (Java based server)";
16-
//public static String ROOT ="C:\\root\\"; //Our files for the WebServer exist inside this folder
17-
public static String ROOT;// = xmlParser.getRootDirectory();
18-
public static File ROOTPATH ;//= new File (ROOT);
19-
//public static int portNumber = 8000;
20-
public static int portNumber ;//= xmlParser.getListenPort();
19+
public static String ROOT;
20+
public static File ROOTPATH ;
21+
public static int portNumber ;
2122
public static int statPortNumber;
23+
2224
//Text files for logs
2325
public static String ACCESS;
2426
public static String ERROR;
2527
public static File ACCESSPATH;
2628
public static File ERRORPATH;
29+
2730
//streams to write in logs
2831
public static PrintWriter writerAccess,writerError;
32+
2933
//blocking queue for request objects
3034
public static BlockingQueue<reqOb> msgQ = new ArrayBlockingQueue<reqOb>(10);
3135

@@ -37,10 +41,16 @@ public class mainServer{
3741
public static volatile int countCons=0; //+1: in clientThread, line 246
3842
public static volatile int countErrors=0; //+1: in clientThread, line 256
3943

44+
45+
//etc
46+
public static Socket clientSocket;
47+
public static BufferedReader in ;
48+
4049
public static void main(String[] args) throws IOException, BindException, InterruptedException{
4150

51+
//init
4252
String request="",inputLine="",userStr="",remoteAd="";
43-
BufferedReader in = null;
53+
//BufferedReader in = null;
4454
PrintWriter out = null;
4555
OutputStream data =null;
4656

@@ -74,52 +84,72 @@ public static void main(String[] args) throws IOException, BindException, Interr
7484
//create a serverSocket, using the given port
7585
ServerSocket serverSocket = new ServerSocket(portNumber);
7686

77-
//initiate thread for statistics port, code in statThread class
87+
//initiate thread for statistics port, code inside statThread class
7888
statThread statistics= new statThread();
7989
statistics.start();
80-
//initiate thread for sending response to server port, code in clientThread class
90+
91+
/*
92+
initiate 2 concurrent workers-threads
93+
for sending response to server port, code in clientThread class
94+
*/
8195
clientThread t1= new clientThread();
8296
t1.start();
97+
98+
//Uncomment the following if you want to have 2 workers and test the concurrency
99+
/*
83100
clientThread t2= new clientThread();
84101
t2.start();
85-
102+
*/
86103

87104

88105
while(true ){ //run forever
89106

90107
/*
91-
create a socket(clientSocket) for the client, connect them to the Server and then create:
92-
1 InputStream : BufferedReader in
93-
2 OutputStreams : PrintWriter out ( for the HTTP Response) , OutputStream data( for file sending)
94-
*/
95-
Socket clientSocket = serverSocket.accept();
108+
create a socket(clientSocket) for the client, connect them to the Server and then create:
109+
1 InputStream : BufferedReader in
110+
2 OutputStreams : PrintWriter out ( for the HTTP Response) , OutputStream data( for file sending)
111+
*/
112+
//Socket
113+
clientSocket = serverSocket.accept();
96114
remoteAd =clientSocket.getRemoteSocketAddress().toString();
97115
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
98116
out = new PrintWriter(clientSocket.getOutputStream(), true);
99117
data = new BufferedOutputStream( clientSocket.getOutputStream());
118+
100119
try{
120+
101121
//GET HTTP REQUEST from client
102122
while ((inputLine = in.readLine()) != null) {
103123
if (inputLine.startsWith("GET")){
104-
request=request + inputLine+"\n";
124+
request=request + inputLine+"\n"; //1st line of GET request
105125
}
106126
else if(inputLine.startsWith("User")){
107-
userStr=userStr + inputLine+"\n";
127+
userStr=userStr + inputLine+"\n"; //User-Agent Line of GET request
108128
}
109-
else if(inputLine.startsWith("Accept")){
129+
else if(inputLine.startsWith("Accept")){
110130
break;
111131
}
112132
}
113133
/*
114134
Send (1st line of) GET REQUEST to send
115135
the appropriate response to our client
116136
*/
117-
if ( (request!="" )&&(request!= null) ) {
137+
if ( (request!="" ) && (request!= null) ) {
118138
try{
139+
119140
//put the info for the specific request in queue
120141

142+
/*
143+
Now, we insert all the required data for the response inside a "reqOb" object.
144+
See "reqOb" class and its constructor for more information.
145+
*/
121146
reqOb curReq = new reqOb(request,userStr,remoteAd,out,data);
122-
msgQ.put(curReq);
147+
148+
//put the object(and its data) inside the BlockingQueue
149+
msgQ.put(curReq);
150+
151+
//t2.start();
152+
123153
}
124154
catch(InterruptedException e){
125155
StringWriter sw = new StringWriter();
@@ -130,6 +160,12 @@ else if(inputLine.startsWith("Accept")){
130160
//Response sent to client, time to close streams/sockets and wait for another request.
131161
request="";
132162
userStr="";
163+
164+
//out.close();
165+
//data.close();
166+
//in.close();
167+
//clientSocket.close();
168+
//System.out.println("here");
133169
}
134170
}
135171
catch(Exception E){ //in case something bad happens

‎newPort.class

-15.1 KB
Binary file not shown.

‎newPort.java

-871
This file was deleted.

‎newPort.txt

Whitespace-only changes.

‎readme_first.txt

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
2+
Classes explanation:
3+
4+
mainServer : our main thread for the server
5+
clientThread : worker thread that takes the required data and sends the response
6+
statThread : statistics thread
7+
xmlParser : XML Parser for the configuration
8+
reqOb : constructs an object with the required data for the clientThread
9+
10+
Program explanation:
11+
mainServer runs a Web-Server continously in its main thread.
12+
It can support 2 threads-workers(clientThread class) which handle the response on port 8000.
13+
Also, on another thread, we have port 8001 that shows the Statistics about the server.
14+
15+
About XML Parsing:
16+
The Server is configured to run at /root/ directory.
17+
(In Windows, it's C:/root/ )
18+
19+
"config.xml" file is in a different format than the example that you provide us.
20+
(As said in the lecture, we could make our own XML file from the beginning)
21+
You do not have to place the configuration file as an argument when running the program.
22+
You just need to have it under the same directory with the executable.
23+
If you want to change a directory or a port for the server to use, just edit the config.xml.
24+
It's in a simpler format for the XML DOM Parser libraries to use, without node-kids searching.
25+
If you want it in an alternative form, contact us.
26+
27+
About the logs:
28+
access_log.txt and error_log.txt are created under /root/.
29+
30+
About concurrency-threads :
31+
Our program can support 2 workers that send responses.
32+
We use a BlockingQueue where we load there the required data for the request.
33+
The workers take the objects from the queue and work for them sending the response.
34+
This is a technique to solve concurrency problems since when a worker tries to take an object
35+
from the BlockingQueue and it's null, the worker blocks until an object gets put into the queue for
36+
him to work!
37+
Also, we added "synchronized" prefix on some methods in clientThread (worker class) so only one
38+
thread runs the method at the time and doesn't interrupt the other.
39+
Just like the 'locks' example we saw in the lectures.
40+
41+
Last but not least, uncomment line 99-100 in mainServer to test the second worker.
42+
43+
Problems/Caution! :
44+
1)According to your computer and your browser, you might see some problems in concurrency as the program might try to send
45+
data to a closed(by false) socket.
46+
This corresponds to line 356 in clientThread class.
47+
This error can occur when the local network system aborts a connection,
48+
such as when WinSock closes an established connection after data retransmission fails
49+
(receiver never acknowledges data sent on a datastream socket)
50+
51+
2)Given "mime-types.txt" had a double entry for .mp4 , which blocked our browsers from playing the video.
52+
We deleted the one entry, so please use our mime-types.txt file for testing.
53+
54+
3)As said previously, there is no need to put the .xml config file as an argument anymore.
55+
We do this automatically!
56+
57+
Contact:
58+
Eleftherios Panagiotis Loukas : eloukas@uth.gr
59+
Katerina Kanellopoulou : akanellop@uth.gr
60+
61+
62+
63+

‎reqOb.class

-554 Bytes
Binary file not shown.

‎reqOb.java

+3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
//package ce325.hw2;
12
import java.io.*;
23
import java.util.*;
34
import java.lang.*;
45
import java.text.*;
56

7+
8+
69
public class reqOb{
710
public String request;
811
public String userStr;

‎statThread.class

-3 KB
Binary file not shown.

‎statThread.java

+20-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1+
//package ce325.hw2;
2+
13
import java.net.*;
24
import java.io.*;
35
import java.util.*;
46
import java.lang.*;
57
import java.text.*;
68
import java.nio.file.Files;
79

8-
10+
/*
11+
statThread : class that gives us statistics about the server in 8001 port
12+
*/
913
public class statThread extends Thread{
1014

1115
public void run(){
@@ -18,6 +22,7 @@ public void run(){
1822
public static void openSocket() throws IOException, BindException{
1923
String inputLine="";
2024
ServerSocket statSocket = new ServerSocket(mainServer.statPortNumber);
25+
2126
while(true){
2227
try{
2328
Socket statClient = statSocket.accept();
@@ -43,13 +48,21 @@ public static void openSocket() throws IOException, BindException{
4348
}
4449
}
4550
}
46-
/*builds and sends the html page and the http response for the statisstics requests*/
51+
52+
/*
53+
statHTML method
54+
takes PrintWriter out as an argument so it can send an HTTP RESPONSE and then
55+
builds and sends the html page and the http response for the statisstics requests
56+
*/
4757
public static void statHTML(PrintWriter out)throws Exception{
58+
4859
//Create a StringBuilder object, called "html", in which we build the html(you don't say!)
4960
StringBuilder html = new StringBuilder();
50-
//Start of HTML
61+
62+
//Start of HTMLbuilding
5163
html.append( "<html>\r\n" );
5264
html.append( "<head>\r\n" );
65+
5366
//Title
5467
html.append( "<title>Statistics For Server</title>\r\n" );
5568
html.append( "</head>\r\n" );
@@ -62,9 +75,10 @@ public static void statHTML(PrintWriter out)throws Exception{
6275
}
6376
html.append( "<h4>Total number of connections : "+mainServer.countCons+"</h4>\r\n" );
6477
html.append( "<h4>Total number of errors : "+mainServer.countErrors+"</h4>\r\n" );
65-
//End of HTML
78+
//End of HTML building
6679
html.append( "</body>\r\n" );
6780
html.append( "</html>\r\n" );
81+
6882
//Send HTTP RESPONSE
6983
Date date = new Date();
7084
out.print("HTTP/1.1 200 OK" + "\r\n");
@@ -73,10 +87,11 @@ public static void statHTML(PrintWriter out)throws Exception{
7387
out.print( "Content-length: " + html.toString().length() + "\r\n" );
7488
out.print( "Connection: close\r\n" );
7589
out.print( "Content-type: text/html\r\n\r\n" );
90+
7691
//SEND HTML RESPONSE
7792
out.print( html.toString() );
7893
//flush
79-
out.flush();
94+
out.flush();
8095
}
8196

8297
}

‎test2.java

-562
This file was deleted.

‎test3.class

-11.7 KB
Binary file not shown.

‎test3.java

-636
This file was deleted.

‎xmlParser.class

-2.95 KB
Binary file not shown.

‎xmlParser.java

+4-16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//package ce325.hw2;
2+
13
import java.io.File;
24
import java.io.IOException;
35
import java.util.StringTokenizer;
@@ -42,19 +44,16 @@ public static void buildDoc(){
4244

4345
//optional, but may be recommended --IS IT NEEDED????
4446
doc.getDocumentElement().normalize();
45-
//check
4647

4748
/*
4849
//doc.getElementsByTagName("method") returns a NodeList.
4950
//doc.getElementsByTagName("method").item(0) - returns a Node.
5051
//doc.getElementsByTagName("method").item(0).getTextContent() returns the value
5152
*/
5253

53-
//System.out.println("before getting elements");
54-
//port1 = doc.getElementsByTagName("listen port").item(0).getTextContent();
54+
5555
port1 = doc.getElementsByTagName("listenport").item(0).getTextContent();
56-
//System.out.println("got port1 " + port1);
57-
//System.out.println("after listenport");
56+
5857
port2 = doc.getElementsByTagName("statisticsport").item(0).getTextContent();
5958
//System.out.println("got port2 " + port2);
6059

@@ -66,17 +65,6 @@ public static void buildDoc(){
6665
//System.out.println("got rootDirectory " + rootDirectory);
6766

6867

69-
/*
70-
System.out.println("\nbefore tokenizer\n");
71-
System.out.println(port1);
72-
*/
73-
//why is this used???What do we split?
74-
/*
75-
StringTokenizer tokenizer = new StringTokenizer(port1, "\"");
76-
while(tokenizer.hasMoreTokens()){
77-
port1 = tokenizer.nextToken();
78-
79-
*/
8068
try{
8169
//ports are returned as a string, so we type cast them to integers
8270
listenPort = Integer.parseInt(port1);

0 commit comments

Comments
 (0)
Please sign in to comment.