最近,由于计算机网络课程,自己动手写了一个静态服务器,感觉挺好玩的,慢慢了解到tomcat服务器的原理,而我这次做的只做了GET和PUT方法,废话不多说,下面上代码:
package com.xanxus.http;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ThreadedServer {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(8000);
while (true) {
Socket socket = serverSocket.accept();
new Thread(new SocketRunnable(socket, args[0])).start();// 注意,这里用内部类不行
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void putOutput(OutputStream outputStream, int stateCode,
String fileType, String fileName, BufferedReader requestReader)
throws IOException {
String clientRequest = null;
int contentLength = 0;// 请求实体长度
while ((clientRequest = requestReader.readLine()) != null) {
// 获取实体长度
if (clientRequest.toLowerCase().startsWith("content-length")) {
contentLength = Integer.parseInt(clientRequest
.substring(clientRequest.indexOf(":") + 2));
} else if (clientRequest.equals("")) {
// 空行,首部行结束
break;
}
}
// 读取实体
File putFile = new File(fileName);
FileOutputStream fos = new FileOutputStream(putFile);
char[] requestEntity = new char[1024];
int count = 0;
while (contentLength > 0
&& (count = requestReader.read(requestEntity)) != -1) {
fos.write(requestEntity.toString().getBytes());
contentLength -= count;
}
fos.close();
// 写响应报文
if (fileType != null) {
// 输出首部行
StringBuilder stringBuilder = new StringBuilder();
switch (stateCode) {
case 200:
stringBuilder.append("HTTP/1.0 200 OK\r\n");
// mime type
switch (fileType) {
case "jpg":
stringBuilder.append("Content-Type: image/jpeg" + "\r\n");
break;
case "html":
stringBuilder.append("Content-Type: text/html" + "\r\n");
break;
case "gif":
stringBuilder.append("Content-Type: image/gif" + "\r\n");
break;
case "png":
stringBuilder.append("Content-Type: image/png" + "\r\n");
break;
default:
stringBuilder.append("Content-Type: text/plain" + "\r\n");
break;
}
break;
case 404:
stringBuilder.append("HTTP/1.0 404 Not Found\r\n");
break;
case 201:
stringBuilder.append("HTTP/1.0 201 created\r\n");
break;
}
stringBuilder.append("Server: LFY/0.1\r\n");
stringBuilder.append("Connection: close\r\n");
stringBuilder.append("\r\n");
outputStream.write(stringBuilder.toString().getBytes());
outputStream.flush();
}
outputStream.close();
}
public static void getOutput(OutputStream outputStream, int stateCode,
String fileType, String fileName) throws IOException {
if (fileType != null) {
// 输出首部行
StringBuilder stringBuilder = new StringBuilder();
switch (stateCode) {
case 200:
stringBuilder.append("HTTP/1.0 200 OK\r\n");
// mime type
switch (fileType) {
case "jpg":
stringBuilder.append("Content-Type: image/jpeg" + "\r\n");
break;
case "html":
stringBuilder.append("Content-Type: text/html" + "\r\n");
break;
case "gif":
stringBuilder.append("Content-Type: image/gif" + "\r\n");
break;
case "png":
stringBuilder.append("Content-Type: image/png" + "\r\n");
break;
case "avi":
stringBuilder.append("Content-Type: video/x-msvideo" + "\r\n");
break;
case "mp4":
stringBuilder.append("Content-Type: video/mpeg" + "\r\n");
break;
case "ogg":
stringBuilder.append("Content-Type: audio/ogg" + "\r\n");
break;
default:
stringBuilder.append("Content-Type: text/plain" + "\r\n");
break;
}
break;
case 404:
stringBuilder.append("HTTP/1.0 404 Not Found\r\n");
break;
case 403:
stringBuilder.append("HTTP/1.0 403 Forbidden\r\n");
break;
}
stringBuilder.append("Server: LFY/0.1\r\n");
stringBuilder.append("Connection: close\r\n");
stringBuilder.append("\r\n");
outputStream.write(stringBuilder.toString().getBytes());
outputStream.flush();
// 文件存在才输出文件
if (stateCode == 200) {
// 输出请求文件
int length = -1;
byte[] fileContent = new byte[1024];
FileInputStream fis = new FileInputStream(fileName);
// 一律用字节流,因为有可能请求二进制文件
while ((length = fis.read(fileContent)) != -1) {
outputStream.write(fileContent, 0, length);
}
} else if (stateCode == 404) {
// 输出404返回页面
String notFoundString = "<html><head><title>404</title></head><body><center><h1>Error:404 The requested URL was not found on this server.</center></body></html>";
outputStream.write(notFoundString.getBytes("UTF-8"));
outputStream.flush();
}
outputStream.flush();
}
outputStream.close();
}
}
class SocketRunnable implements Runnable {
Socket socket = null;
String rootPath = null;
public SocketRunnable(Socket socket, String rootPath) {
// TODO Auto-generated constructor stub
this.socket = socket;
this.rootPath = rootPath;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
OutputStream responseStream = socket.getOutputStream();
// 客户端发送的请求字符串,方法,请求文件路径,文件类型,主机名
String clientRequest = null, method = null, filePath = null, fileType = null, hostName = null;
Boolean isConnection = false;
StringBuffer responseBuilder = new StringBuffer(), fileContentBuilder = new StringBuffer();// 响应报文,请求文件内容
int stateCode = 200;// 状态码
Boolean isPut = false, isClf = false;
// 获取首部行
if ((clientRequest = bufferedReader.readLine()) != null) {
System.out.println("From:"
+ socket.getInetAddress().getHostAddress() + "\r\n\t"
+ clientRequest);
// 第一行就返回
if (clientRequest.startsWith("GET")
|| clientRequest.startsWith("PUT")) {
method = clientRequest.substring(0, 3);
// 第一个斜杠的位置
int slashPosition = clientRequest.indexOf("/");
filePath = rootPath
+ clientRequest.substring(slashPosition,
clientRequest.indexOf(" ", slashPosition))
.replace("/", "\\");// 把路径分隔符‘/’替换为‘\’
// 默认请求文件
if (filePath.equals(rootPath + "\\")) {
filePath = rootPath + "\\index.html";
}
File requestFile = new File(filePath);
// 判断请求文件是否存在
if (!requestFile.exists()) {
stateCode = 404;
}
fileType = filePath
.substring(filePath.lastIndexOf(".") + 1);
// 判断请求文件类型,设置输出的mime type
switch (fileType) {
case "html":
case "htm":
fileType = "html";
break;
case "jpg":
case "jpeg":
fileType = "jpg";
break;
case "gif":
fileType = "gif";
break;
}
if (method.equals("GET")) {
ThreadedServer.getOutput(responseStream, stateCode,
fileType, filePath);
socket.close();
} else if (method.equals("PUT")) {
ThreadedServer.putOutput(responseStream, stateCode,
fileType, filePath, bufferedReader);
socket.close();
}
} else if (clientRequest.equals("\r\n")
|| clientRequest.equals("")) {
}
}
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
资源下载可以到http://download.csdn.net/detail/xanxus46/4745329
是否觉得很给力,以后有时间,一定会继续写动态的内容,如jsp,想一下都觉得兴奋。