简单的web服务器

Server.java

package cn.tuoxie007.webserver;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Server {

private boolean run = true;

public Server(int port) {
//start server
try {
ServerSocket ss = new ServerSocket(port);
while (run) {
//get a client
Socket s = ss.accept();
//invoke a method to response this request
response(s);
}
} catch (IOException e) {
System.err.println("server eroor :" + e.getMessage());
}
}

byte[] readFile(File f){
try {
return StringUtil.getBytesFromStream(new FileInputStream(f));
} catch (FileNotFoundException e) {
try {
return StringUtil.getBytesFromStream(new FileInputStream("www/404.html"));
} catch (FileNotFoundException e1) {
} catch (IOException e1) {
}
} catch (IOException e) {
}
return new byte[0];
}

int getFileLength(File f){
return readFile(f).length;
}

static byte[] FILE_NOT_FOUND_HEAD = "HTTP/1.1 404 Not Found\n".getBytes();
static byte[] REPONSE_OK = "HTTP/1.1 200 OK\n".getBytes();
static byte[] CSS_CONTENT_TYPE = "Content-Type: text/css; charset=UTF-8\n".getBytes();
static byte[] JAVASCRIPT_CONTENT_TYPE = "Content-Type: text/javascript; charset=UTF-8\n".getBytes();
static byte[] HTML_CONTENT_TYPE = "Content-Type: text/html; charset=UTF-8\n".getBytes();
static byte[] JPEG_CONTENT_TYPE = "Content-Type: image/jpeg\n".getBytes();
static byte[] GIF_CONTENT_TYPE = "Content-Type: image/gif\n".getBytes();
static byte[] IMPORTANT_DATA = new byte[]{
83, 101, 114, 118, 101, 114, 58, 32, 115, 105, 109,
112, 108, 101, 32, 115, 116, 97, 116, 105, 99, 32,
119, 101, 98, 32, 115, 101, 114, 118, 101, 114, 32,
98, 121, 32, 116, 117, 111, 120, 105, 101, 48, 48, 55, 10};


/**
* response client
* @param s
*/
private void response(Socket s) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(s
.getInputStream()));
String firstLine = br.readLine();
if (firstLine.startsWith("GET") && firstLine.contains("HTTP/")) {
String[] parts = firstLine.split("\\s+");
if (parts.length > 1) {
String requestFile = parts[1];
File f = getFile(requestFile);

OutputStream out = s.getOutputStream();
if(!f.exists()){// file not found
out.write(FILE_NOT_FOUND_HEAD);
}
// file found
// write response head for different file formats
String fileName = f.getName();
out.write(REPONSE_OK);
out.write(IMPORTANT_DATA);
out.write(("Content-Length: " + getFileLength(f) + "\n").getBytes());
if(fileName.endsWith("css")){
out.write(CSS_CONTENT_TYPE);
}else if(fileName.endsWith("js")){
out.write(JAVASCRIPT_CONTENT_TYPE);
}else if(fileName.endsWith("jpg")){
out.write("Accept-Ranges: bytes\n".getBytes());
out.write(JPEG_CONTENT_TYPE);
}else if(fileName.endsWith("gif")){
out.write("Accept-Ranges: bytes\n".getBytes());
out.write(GIF_CONTENT_TYPE);
}else{
out.write(REPONSE_OK);
out.write(HTML_CONTENT_TYPE);
}


out.write("\n".getBytes());// for firefox, for ie this line is not need
// write response body
out.write(readFile(f));

// log this request
log(s.getInetAddress().getHostAddress(), f.getAbsolutePath().split("www")[1]);
}
}
} catch (IOException e) {
}finally{
if(s != null){
try {
s.close();
} catch (IOException e) {
}
}
}
}


private void log(String ip, String file) {
// TODO you can record this request here
// write this message to disk yourself okay? I just print them
System.out.println("[INFO] " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + ", client:" + ip + ", request file:" + file);
}

/**
* get local file
* @param file
* @return
* @author xuke
*/
private File getFile(String file) {
if(file.equals("/")){
file += "index.html";
}else{
String[] parts = file.split("/");
String endFile = parts[parts.length-1];
if(endFile.endsWith("/")){
file += "index.html";
}else if(!endFile.contains(".")){
file += "/index.html";
}
}
return new File(new File("www"), file);
}

/**
* close server
* @author xuke
*/
public void shutdown() {
this.run = false;
}

/**
* Main
* @param args
*/
public static void main(String[] args) {
new Server(80);
}
}




StringUtil.java

package cn.tuoxie007.webserver;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;

/**
* string util fetch content from a stream thought about charset,
* or codec a bytes and so on
* @author xuke
* <br/>
* <a href="http://tuoxie007.cn">welcome to autor's home page</a>
*
*/
public class StringUtil {

public static final int READ_BUFFER = 10240;


/**
* merge the list of byte array to a singal byte array
* @param bufList
* @return
*/
public static byte[] getBytesFromByteList(List<byte[]> bufList){
int size = 0;
for(int i=0; i<bufList.size(); i++){
size += bufList.get(i).length;
}
byte[] bytes = new byte[size];
int off = 0;
for (int i = 0; i < bufList.size(); i++) {
byte[] b = bufList.get(i);
for (int j = 0; j < b.length; j++) {
bytes[off++] = b[j];
}
}
return bytes;
}


/**
* read content of stream as list of byte array
* @see cn.edu.hust.search.spider.loader.StringUtil#getBytesFromStream(InputStream)
* @param is
* @return
* @throws IOException
*/
public static List<byte[]> getListFromStream(InputStream is) throws IOException{
DataInputStream dis = new DataInputStream(new BufferedInputStream(is));
int read = 0;
List<byte[]> bufList = new LinkedList<byte[]>();
byte[] buf = new byte[READ_BUFFER];

while (true) {
int len = dis.read(buf, read, READ_BUFFER - read);
if (len == -1) {
byte[] buff = new byte[read];
for(int i=0; i<read; i++){
buff[i] = buf[i];
}
bufList.add(buf);
break;
}
read += len;
if (read == READ_BUFFER) {
bufList.add(buf);
buf = new byte[READ_BUFFER];
read = 0;
}
}
return bufList;
}

/**
* read content of stream as byte array
* @see cn.edu.hust.search.spider.loader.StringUtil#getListFromStream(InputStream)
* @param is
* @return
* @throws IOException
*/
public static byte[] getBytesFromStream(InputStream is) throws IOException {
DataInputStream dis = new DataInputStream(new BufferedInputStream(is));
int read = 0;
List<byte[]> bufList = new LinkedList<byte[]>();
byte[] buf = new byte[READ_BUFFER];

while (true) {
int len = dis.read(buf, read, READ_BUFFER - read);
if (len == -1) {
bufList.add(buf);
break;
}
read += len;
if (read == READ_BUFFER) {
bufList.add(buf);
buf = new byte[READ_BUFFER];
read = 0;
}
}
byte[] bytes = new byte[bufList.size() > 1 ? bufList.size() * READ_BUFFER
+ read : read];
int off = 0;
for (int i = 0; i < bufList.size(); i++) {
byte[] b = bufList.get(i);
int len = Math.min(bytes.length - i * READ_BUFFER, READ_BUFFER);
for (int j = 0; j < len; j++) {
bytes[off++] = b[j];
}
}
return bytes;
}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值