ssd8 exercise1答案完整版(仅供参考)

ssd8 exercise1答案完整版(仅供参考)
2012年01月15日
  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 + "" + code + " " + msg + "" + "" + "" + CRLF; //把MIME格式加到输出形式里 String mh = getMIME("text/html", html_page.length()); //把响应的号码加入到输出形式里 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(".h tm")) {
  return "text/html";
  } else if (filename.endsWith(".jpg")||filename.endsWith(".jp eg")) {
  //判断是否以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",header); 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")).getByte s()); 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", 8000); //向屏幕打印 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 = "" + "" + CRLF + "" + code + " " + msg + "" + "" + "" + CRLF; //把MIME格式加到输出形式里 String mh = getMIME("text/html", html_page.length()); //把响应的号码加入到输出形式里 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(".h tm")) { return "text/html"; } else if (filename.endsWith(".jpg")||filename.endsWith(".jp eg")) { //判断是否以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",header); 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")).getByte s()); 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 BufferedReader(new InputStreamReader(socket.getInputStream())); DataOutputStream ToClient =new DataOutputStream(socket.getOutputStream()); // 一直读写直到"\r\n\r\n"; // BufferedOutputStream outToClient = new BufferedOutputStream(socket.getOutputStream()); 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(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.
  ReadMe.doc:(长度有限略掉)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值