Server.java:
//导包
import java.net.*;
import java.io.*;
import java.util.*;
public class Server {//服务器端
//定义端口
static private int PORT =8000;
//回车换行
static private String CRLF = \"\\r\\n\";
//数组大小常量
static private int buffer_size = 99999;
//服务器资源路径
static File root;
/*
获取文件路径,考虑到了各种情况
*/
private static String getFileURI(String uri) {
if (uri.startsWith(\"http://\")) {
return uri.substring(uri.indexOf('/',8)+1);
} else if (uri.startsWith(\"/\")) {
return uri.substring(1);
}else if(uri.startsWith(\"www\")){
return uri.substring(uri.indexOf('/',8)+1);
} else return uri;
}
//创建一个标准的http协议响应格式
private static String makeResponse(int num, String msg, String header) {
return \"HTTP/1.0\" + \" \" + num + \" \" + msg + CRLF + header + CRLF;
}
//创建MIME类型格式
private static String getMIME(String type, int len) {
String mm =
\"Server: SimpleServer/1.0\" + CRLF +
\"Content-type: \" + type + CRLF +
\"Content-length: \" + len + CRLF;
return mm;
}
//出错提示信息
private static String error(int code, String msg) {
//构造html页面
String html_page = \"\" + \"
\" + CRLF +\"
//把MIME格式加到输出形式里
String mh = getMIME(\"text/html\
//把响应的号码加入到输出形式里
String hr = makeResponse(code, msg, mh);
//返回整个输出形式
return hr + html_page;
}
//根据文件名得到文件类型
private static String getType(String filename) {
//判断是否以html/htm结束的文件,并返回string类型
if (filename.endsWith(\".html\")||filename.endsWith(\".htm\")) {
return \"text/html\";
} else if (filename.endsWith(\".jpg\")||filename.endsWith(\".jpeg\")) {
//判断是否以jpg/jpeg结束的文件,并返回string类型
return \"image/jpeg\";
//默认text类型
} else return \"text\";
}
//处理从客户端得到的get指令信息
private static void handleGet(BufferedOutputStream outToClient, String uri) {
try {
String filename =getFileURI(uri);
File f = new File(root, filename);
if (!f.exists()) {
outToClient.write((error(404,\"File not found\")).getBytes());//文件不存在404错误
} else {
//存在时给出输出
String type = getType(f.getName());
String header = getMIME(type,(int) f.length());
String response = makeResponse(200,\"OK\
outToClient.write(response.getBytes());
//建立一个输入流
FileInputStream fstream = new FileInputStream(f);
//创建一个byte数组,用来存放写入的类容
byte[] buffer = new byte[buffer_size];
//判断是否写完
while(fstream.read(buffer) != -1) {
outToClient.write(buffer);
}
}
} catch (IOException e) {
System.out.println(e);
}
}
//处理put指令
private static void handlePut( BufferedReader inFromClient,
BufferedOutputStream outToClient,
String uri, int len) {
try {
String filename = getFileURI(uri);
File f = new File(root, filename);
String reply;
if (f.exists()) {
if (!f.isFile()) {
outToClient.write((error(403,\"Forbidden\")).getBytes());
return;
} else {
reply = error(200, \"OK\");}
} else {
reply = error(201, \"Created\");
}
FileOutputStream fstream = new FileOutputStream(f);
fstream.write(inFromClient.toString().getBytes());
fstream.flush();
fstream.close();
outToClient.write(reply.getBytes());
} catch (IOException ioe) {
System.out.println(3);
}
}
//main函数
public static void main(String [] args) {
//创建一个服务器
ServerSocket serverSocket = null;
//字符数出流
BufferedOutputStream outToClient = null;
//字符输入流
BufferedReader inFromClient = null;
//判断输入的参数是否正确并给出提示
if (args.length != 1) {
System.err.println(\"Usage: Server \");
return;
}
try {//根据参数,创建服务器资源地址
root = new File(args[0]);
if (!root.isDirectory()) {//判断资源文件是否存在,或者是否是一个文件夹.
System.err.println
(root.getAbsolutePath() + \" does not exist or is not a directory\");
return;
}
} catch ( Exception e ) {
System.out.println(\"Exception has occured!\");
return;
}
//创建一个客户端实例
try {
serverSocket = new ServerSocket(PORT);
} catch (Exception e) {
System.out.println(\"Exception has occured!\");
}
//服务器和客户端交互
while (true) {
try {//客户端与服务器连接
Socket socket = serverSocket.accept();
try {
//客户端输出流
outToClient = new BufferedOutputStream(socket.getOutputStream());
//服务器输入流
inFromClient = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
serverSocket.close();
//关闭
boolean inHeader = true; // 循环控制
String header =new String();
String temp;
while (inHeader) {
temp = inFromClient.readLine(); //从客户端得到信息
if (temp == null)
break;
if (inHeader==true&& temp.length() == 0)
inHeader= false;
if (inHeader == true){
header = header + \"\\n\" + temp;
}
}
StringTokenizer st = new StringTokenizer(header);//一个单词一个单词读
String method = st.nextToken();
String uri = st.nextToken();
//判断是否是get/GET
if (method.equals(\"GET\")||method.equals(\"get\")) {
{
handleGet(outToClient, uri);
}
} else if (method.equals(\"PUT\")||method.equals(\"put\")) {//PUT/put
int len = -1;
while(st.hasMoreTokens()) {
String line = st.nextToken();
if (line.startsWith(\"Content-Length:\")) {
String length = line.substring(line.indexOf(\"/\")+1);
len = length.length();
break;
}
}
if (len > 0) {
handlePut( inFromClient, outToClient, uri, len);
} else {
//400错误请求
outToClient.write((error(400, \"Bad Request.\")).getBytes());
serverSocket.close();
}
} else {
serverSocket.close();
outToClient.write((error(501, \"Not Implemented\")).getBytes());
}
} catch (NoSuchElementException e) {
System.out.println(e);
}
outToClient.flush();
socket.close();
outToClient.close();
} catch( Exception e ){
System.out.println(\"失去了和主机的连接。break;
}
}
}
断开连接\");//
}
client.java:
//导入所需要的包
import java.net.*;
import java.io.*;
//客户端程序
public class Client
{
//客户端端口号
private static int PORT = 80;
//静态常量用于给数组规定大小
private static int buffer_size = 8192;
//回车换行
private static String CRLF = \"\\r\\n\";
//从键盘标准输入到缓存
static BufferedReader keyboard = new BufferedReader(new
InputStreamReader(System.in));
//屏幕输出
static PrintWriter screen = new PrintWriter (System.out, true);
//主函数
public static void main( String [] args ) {
try{
//发给服务器的缓存
BufferedOutputStream outToServer = null;
//从服务器得到的
BufferedReader inFromServer = null;
//声明一个有一定大小的数组
byte[]buffer = new byte[buffer_size];
String header = new String();
String body = new String();
//判断是否正确输入参数
if (args.length != 1) {
System.err.println(\"Usage: Client System.exit(0); } //建立一个客户实例 Socket socket = new Socket(\"localhost\ //向屏幕打印 screen.println(args[0] + \" is listening to your request:\"); //从服务器将客户端要的信息读入 inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream())); //把信息写到服务器 outToServer = new BufferedOutputStream(socket.getOutputStream()); //读入键盘输入的信息 String request = keyboard.readLine(); //确保是以回车换行结束 request += CRLF + CRLF; //将键盘输入的信息传给byte数组 buffer = request.getBytes(); //在将此信息传个服务器 outToServer.write(buffer, 0, request.length()); //强制写入到服务器 outToServer.flush(); boolean inHeader = true; String temp; while (true) { //循环控制 temp = inFromServer.readLine(); //从服务器读出类容信息 if (temp == null) //判断是否读完 break; if (inHeader==true && temp.length() == 0) inHeader= false; if (inHeader == true) header = header + \"\\n\" + temp; else body =body+ \"\\n\" + temp; } //打印信息头 screen.println( \"Header: \\n\" ); screen.print( header + \"\\n\" ); screen.flush(); //保存信息到指定文件 screen.println(); screen.print(\"Enter the name of the file to save: \\n\"); screen.flush(); String filename = keyboard.readLine(); File f=new File(\"C:\\\\Documents and Settings\\\\Administrator\\\\\\\\\"+filename); FileOutputStream outfile = new FileOutputStream(f); outfile.write(body.getBytes());//往文件写入信息内容 screen.println(filename+\"默认保存在了桌面上,请查看!\"); 桌面 outfile.flush(); outfile.close(); socket.close(); outToServer.close(); inFromServer.close();//关闭流 }catch(Exception e){//出现异常时,给出以下信息 screen.println(\" 对不起,连接失败。请尝试以下解决方案:\"); screen.println(\" ************************************\"); screen.println(\" ** 1.查看服务器是否已打开 **\"); screen.println(\" ** 2.查看服务器是否支持多线程服务 **\"); screen.println(\" ** 3.结束已运行的服务,重启服务器 **\"); screen.println(\" ************************************\"); } } } ThreadedServer.java: import java.net.*; import java.io.*; import java.util.*; //实现多线程runnable接口 class Handle implements Runnable { static private String CRLF = \"\\r\\n\"; static private int buffer_size = 8192; static PrintWriter stdOut = new PrintWriter (System.out, true); static File root; Socket socket ; public Handle(Socket s,File r){ //构造方法初始化属性 this.socket=s; this.root=r; Thread t=new Thread(this, \"Server Thread\"); t.start(); } //得到请求的文件名 private static String getUriFile(String uri) { if (uri.startsWith(\"http://\")) { return uri.substring(uri.indexOf('/',8)+1); } else if (uri.startsWith(\"/\")) { return uri.substring(1); }else if (uri.startsWith(\"/\")){ return uri.substring(1); } else return uri; } //创建一个标准的http协议响应格式 private static String makeResponse(int code, String msg, String header) { return \"HTTP/1.0\" + \" \" + code + \" \" + msg + CRLF + header + CRLF; } //创建MIME类型格式 private static String getMIME(String type, int len) { String mm = \"Server: SimpleServer/1.0\" + CRLF + \"Content-type: \" + type + CRLF + \"Content-length: \" + len + CRLF; return mm; } //出错提示信息 private static String error(int code, String msg) { //构造html页面 String html_page = \"\" + \" \" //把MIME格式加到输出形式里 String mh = getMIME(\"text/html\ //把响应的号码加入到输出形式里 String hr = makeResponse(code, msg, mh); //返回整个输出形式 return hr + html_page; } //根据文件名得到文件类型 private static String getType(String filename) { //判断是否以html/htm结束的文件,并返回string类型 if (filename.endsWith(\".html\")||filename.endsWith(\".htm\")) { return \"text/html\"; } else if (filename.endsWith(\".jpg\")||filename.endsWith(\".jpeg\")) { //判断是否以jpg/jpeg结束的文件,并返回string类型 return \"image/jpeg\"; //默认text类型 } else return \"text/plain\"; } //处理从客户端得到的get指令信息 private static void handleGet(DataOutputStream ToClient, String uri) { try { //文件不存在404错误 String filename = getUriFile(uri); File f = new File(root, filename); if (!f.isFile()) { ToClient.write((error(404,\"File not found\")).getBytes()); } else { //存在时给出输出 String type = getType(f.getName()); String header = getMIME(type,(int) f.length()); String response = makeResponse(200,\"OK\ ToClient.write(response.getBytes()); //建立一个输入流 FileInputStream fstream = new FileInputStream(f); //创建一个byte数组,用来存放写入的类容 byte[] buffer = new byte[buffer_size]; //判断是否写完 while(fstream.read(buffer) != -1) { ToClient.write(buffer); } } } catch (IOException e) { e.printStackTrace(); } } //处理put指令 private static void handlePut( BufferedReader inFromClient, DataOutputStream outToClient, String uri, int len) { try { String filename = getUriFile(uri); File f = new File(root, filename); String reply; if (f.exists()) { if (!f.isFile()) { outToClient.write((error(403,\"Forbidden\")).getBytes()); return; } else { reply = error(200, \"OK\");} } else { reply = error(201, \"Created\"); } FileOutputStream fstream = new FileOutputStream(f); fstream.write(inFromClient.toString().getBytes()); fstream.flush(); fstream.close(); outToClient.write(reply.getBytes()); } catch (IOException ioe) { ioe.printStackTrace(); } } //覆写run()方法,实现多线程操作 public void run() { try { BufferedReader inFromClient = new InputStreamReader(socket.getInputStream())); DataOutputStream ToClient DataOutputStream(socket.getOutputStream()); // 一直读写直到\"\\r\\n\\r\\n\"; // BufferedOutputStream outToClient BufferedOutputStream(socket.getOutputStream()); boolean inHeader = true; // 循环控制} String header =new String(); String temp; while (inHeader) { temp = inFromClient.readLine(); BufferedReader(new =new = new if (temp == null) break; if (inHeader==true&& temp.length() == 0) inHeader= false; if (inHeader == true){ header = header + \"\\n\" + temp; } } StringTokenizer st = new StringTokenizer(header);//一个单词一个单词读 String method = st.nextToken(); String uri = st.nextToken(); //判断是否是get/GET if (method.equals(\"GET\")||method.equals(\"get\")) { { handleGet(ToClient, uri); } //判断是否是PUT/put } else if (method.equals(\"PUT\")) { //算出put 文件类容的长度 int len = -1; while(st.hasMoreTokens()) { String line = st.nextToken(); if (line.startsWith(\"Content-Length:\")) { String length = line.substring(line.indexOf(' ')+1); len = new Integer(length).intValue(); break; } } //大于0的话,继续put if (len > 0) { handlePut( inFromClient, ToClient, uri, len); } else { //如果出错给出错误提示 ToClient.write((error(400, \"Bad Request.\")).getBytes()); } } else { //如果不是get/put给出错误提示 ToClient.write((error(501, \"Not Implemented\")).getBytes()); } socket.close(); } catch (NoSuchElementException nse) { nse.printStackTrace(); } catch(IOException e){ e.printStackTrace(); } } } public class ThreadedServer { //main函数 static PrintWriter stdOut = new PrintWriter (System.out, true); static private int PORT =8000; public static void main(String [] args) { File root; ServerSocket serverSocket = null; //输入参数是否正确 if (args.length != 1) { System.err.println(\"Usage: Server \"); return; } //判断资源文件是否存在,或者是否是一个文件夹 try { root = new File(args[0]); if (!root.isDirectory()) { System.err.println (root.getAbsolutePath() + \" does not exist or is not a directory\"); return; } } catch ( Exception e ) { e.printStackTrace(); return; } //创建一个服务器端,监听8000端口等待连接 try { serverSocket = new ServerSocket(PORT); } catch (Exception e) { e.printStackTrace(); } //服务器一直等待用户的连接 while (true) { try { Socket consocket = serverSocket.accept(); new Handle(consocket, root); } catch( Exception e ){ stdOut.println(e); e.printStackTrace(); } } } } differences.txt: Describe the Differences between HTTP/1.0 and HTTP/1.1 : 1. HTTP 1.0 use Non-Persistent Connections. It only supports one-to-one relationship of IP addresses and servers; a new connection have to been made every time the client make a new request,and the server do not make record of the information about the client. HTTP 1.1 supports persistent connections. 2.HTTP/1.1 support the Host request-header, avoiding the case that a port in an ip only can have one web site in http/1.0. 3.in http/1.0 the client can not send a new request before the last request is recieved by the client. but the http/1.1 can do it and reduced the whole request time. HTTP/1.1 also have the function of client identify , caching, and state management. but HTTP/1.0 does not. 因篇幅问题不能全部显示,请点此查看更多更全内容\" + code + \" \" + msg + \"
\" + \"\" + \"\" + CRLF;