Web server with thread pool

The goals of this project are:

  • to understand the basic elements of the World Wide Web and its protocols.
  • to learn how real-world multi-threaded servers are built.
  • to apply scheduling algorithms to a working system.
  • gain experience in reading and modifying existing code.
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
package http;

import java.io.*;
import java.net.*;
import java.util.Scanner;

/**
* John
*/

public class HttpClient {
/* 设置端口为8888 */
private static final int port = 8080;

public static void main( String[] args )
{
try {
System.out.println( "请输入你要得到的文件:" );
Scanner scanner = new Scanner( System.in );
String filename = scanner.next();

/* 连接服务器 */
Socket s = new Socket( "localhost", port );
/* 发送请求头 */
PrintStream writer = new PrintStream( s.getOutputStream() );
writer.println( "GET /" + filename + " HTTP/1.1" );
writer.println( "Host:localhost" );
writer.println( "connection:keep-alive" );
writer.println();
writer.flush();
/* 发送请求体 */

/*
* 接受响应状态 响应成功(状态码200)--保存资源到本地磁盘
* 跳过响应中的前四行,开始读取相应的数据
*/
InputStream in = s.getInputStream();
BufferedReader reader = new BufferedReader( new InputStreamReader( in ) );
String firstLineOfResponse = reader.readLine(); /* HTTP/1.1 200 ok */
String secondLineOfResponse = reader.readLine(); /* Content-Type:text/html */
String threeLineOfResponse = reader.readLine(); /* Content-Length: */
String fourLineOfResponse = reader.readLine(); /* 空行 */

System.out.println( firstLineOfResponse );
System.out.println( secondLineOfResponse );
System.out.println( threeLineOfResponse );
System.out.println( fourLineOfResponse );

if ( firstLineOfResponse.endsWith( "OK" ) )
{
/*
* 读取响应文件,保存数据
* success
*/
byte[] b = new byte[1024];
OutputStream out = new FileOutputStream( "d:/client/" + filename );
int len = in.read( b );
while ( len != -1 )
{
out.write( b, 0, len );
len = in.read( b );
}
System.out.println( "数据传输结束" );
out.close();
in.close();
}else {
/*
* 响应失败(状态码404)
*/
StringBuffer result = new StringBuffer();
String line = "";
while ( (line = reader.readLine())!= null )
{
result.append( line );
}
reader.close();
System.out.println( result );
}
} catch ( Exception e ) {
e.printStackTrace();
}
}
}

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
package http;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
* John
*/

public class HttpServer {

private static final int port=8080;

public static void main(String[] args) {

ServerSocket ss=null;
Socket s=null;
ThreadPoolExecutor threadPool=null;
String Mode="FCFS";
//String Mode="SFF";

try {
ss=new ServerSocket(port);
if(Mode=="FCFS"){
threadPool = new ThreadPoolExecutor(2, 4, 3,
TimeUnit.SECONDS, new PriorityBlockingQueue<Runnable>(3),
new ThreadPoolExecutor.DiscardOldestPolicy());
}if(Mode=="SFF"){
threadPool = new ThreadPoolExecutor(2, 4, 3,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),
new ThreadPoolExecutor.DiscardOldestPolicy());
}

while(true){
//接收用户连接,触发accept()
s=ss.accept();
threadPool.execute(new TaskThread(s));
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
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
package http;

import java.io.*;
import java.net.Socket;

/**
* John extends Thread
*/

public class TaskThread implements Runnable, Comparable<TaskThread>{
private Socket socket = null;
private BufferedReader reader = null;
private PrintWriter writer = null;
private long priority;

public TaskThread(Socket s)
{
socket = s;
}

public void run()
{
try {
OutputStream out = socket.getOutputStream();
reader = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );

String firstlineofrequest = reader.readLine();
String uri = firstlineofrequest.split( " " )[1];
writer = new PrintWriter( out );

File f = new File( "d:/server/" + uri );
long fileLength=f.length();
setPriority(fileLength);
if ( f.exists() )
{
FileInputStream file = new FileInputStream( "d:/server/" + uri );
writer.println( "HTTP/1.1 200 OK" );
writer.flush();
if ( uri.endsWith( ".html" ) )
{
writer.println( "Content-Type:text/html" );
writer.flush();
}else if ( uri.endsWith( ".jpg" ) )
{
writer.println( "Content-type:image/jpg" );
writer.flush();
}else {
writer.println( "Content-type:application/octet-stream" );
writer.flush();
}
/* 读取剩下三行 */
for ( int i = 0; i < 3; i++ )
{
reader.readLine();
}


/*有文件 */
writer.println( "Content-length:" + file.available() );
writer.println(); /* 根据http协议,先发一个空行 */
writer.flush();
try {
Thread.sleep( 1000 );
} catch ( InterruptedException e ) {
e.printStackTrace();
}

byte[] b = new byte[1024];
int len = 0;
len = file.read( b );
while ( len != -1 )
{
out.write( b, 0, len );
System.out.println( "1024" );
len = file.read( b );
out.flush();
}
out.close();
}else {
writer.println( "HTTP/1.1 404 Not Found" );
writer.println( "Content-Type:text/plain" );
writer.println( "Content-Length:20" );
writer.println();
writer.println( "Can Not Found File" );
writer.flush();
}
} catch ( IOException e ) {
e.printStackTrace();
}
}

public void setPriority(long fileLength){
this.priority=fileLength;
}
public long getPriority(){
return this.priority;
}

@Override
public int compareTo(TaskThread o) {
// TODO Auto-generated method stub
return priority < o.getPriority() ? 1 : (priority > o.getPriority() ? -1 : 0);
}
}