浏览器与服务端的通信

来源:互联网 发布:电脑没网络手机能连上 编辑:程序博客网 时间:2024/05/26 09:53

服务端代码:

public class WebServer {    private ServerSocket server;    /*     * 线程池,管理用于处理客户端请求的线程     */    private ExecutorService threadPool;    /**     * 构造方法,用于初始化服务端程序     * @throws Exception     */    public WebServer() throws Exception{    try{    server=new ServerSocket(8080);    threadPool=Executors.newFixedThreadPool(100);    }catch(Exception e){    throw e;    }    }        public void start(){    try{    while(true){    System.out.println("等待客户端连接");    Socket socket=server.accept();    System.out.println("客户端已连接");    /*     * 将处理该客户端请求的任务交给线程池     *      */    threadPool.execute(new ClientHandler(socket));        }    }catch(Exception e){    e.printStackTrace();    }    }      public static void main(String[] args) {try{WebServer server=new WebServer();server.start();}catch(Exception e){e.printStackTrace();System.out.println("服务端启动失败!");}}    }

HttpContent:

/** * 定义HTTP协议中的相关信息 * @author live * */public class HttpContent {/* * 回车 */public static final int CR=13;/* * 换行 */public static final int LF=10;}

ClientHandler:

/** * 处理客户端请求 * @author live * */public class ClientHandler implements Runnable{private Socket socket;public ClientHandler(Socket socket){this.socket=socket;}public void run(){try{/*     * HTTP协议中的请求信息格式:     * 请求行       资源                    协议               换行     * GET/index.html  HTTP1.1 CRLF(请求方式) POST     * 消息报头     * 消息正文     *      * 以行为单位发送至服务端 每行结尾以(CR LF)     * CR:回车  LF:换行     * http://localhost:8080     */    //获取输入流,读取客户端发送过来的数据InputStream in=socket.getInputStream();        //读取一行字符串,请求行信息//Method Request-URI Http-version(CRLF)//如://GET/index.html HTTP/1.1CRLF//生成HttpRequest表示请求信息HttpRequest request=new HttpRequest(in);if(request.getUri()!=null){//    String line=readline(in);//    System.out.println("line:"+line);//    if(line.length()>0){//    /*//     * 解析Request-URI//     * 1:按照空格拆分请求行//     * 2:取出第二部分//     *///    String[] data=line.split("\\s");//空格字符/s//    String uri=data[1];//    System.out.println("uri:"+uri);//        int start=line.indexOf("/");//        int end=line.indexOf("H");//        String str=line.substring(start+1, end);//        System.out.println(str.trim());    /*     * 回应客户端对应的资源     * HTTP中响应的格式:     * 1:状态行     * 2:响应头     * 3:响应正文     * 状态行格式:     * HTTP-Version Status_code Reason_phrase CRLF     * HTTP协议                     状态代码                状态描述CRLF     * 例如:     * HTTP/1.1  200 OK  CRLF     * 2:响应头     * 响应头注明很多返回的信息,按行输出     * 常见:     * Content-Type:用来指明发送给接收者的媒体类型     * 常见的Content-Type:     * text/html:HTML格式文件(网页)     * text/xml:XML格式文件     * image/gif:gif格式图片     * image/jpeg:jpeg格式图片     * image/png:png格式图片     * Content-Length,用来指明发送给接受者实体正文的长度     * 简单的说就是发送过去的数据的字节量     *      * HTTP协议要求实际响应客户端时的数据格式:     * HTTP/1.1  200 OK  CRLF       状态行     * Content-Type:text/html  CRLF 响应头信息     * Content-Length:100CRLF       响应头信息     * CRLF 单独发送CRLF指明响应头全部发送完毕     * DATA 实际数据     * TLD   type  length  data     */    OutputStream out=socket.getOutputStream();        //响应状态行    println("HTTP/1.1 200 OK",out);    //发送响应头信息    println("Content-Type:text/html",out);    //加载客户端需要访问的文件资源    File file=new File("webapps"+request.getUri());    println("Content-Length:"+file.length(),out);    println("",out);//单独发送空行表示响应头发送完毕    /*     * 将该文件中所有字节读取出来并发送给客户端     */    BufferedInputStream bis=new BufferedInputStream(    new FileInputStream(file));    int d=-1;    while((d=bis.read())!=-1){    out.write(d);    }    bis.close();    System.out.println("响应客户端完毕!");}       }catch(Exception e){e.printStackTrace();}finally{try{socket.close();}catch(Exception e){e.printStackTrace();}}}/* * 将给定的一行字符串以HTTP协议格式要求按行写出 */private void println(String str,OutputStream out) throws Exception{try {out.write(str.getBytes("ISO8859-1"));out.write(HttpContent.CR);out.write(HttpContent.LF); } catch (UnsupportedEncodingException e) {e.printStackTrace();System.out.println("不受支持的编码");throw e;} catch (IOException e) {e.printStackTrace();throw e;}} }

HttpRequest:

public class HttpRequest {//请求方法  private String method;  //请求资源  private String uri;  //请求协议  private String protocol;  /*   * 构造方法,用于创建HttpRequest实例   *    * @param in 对应客户端输入流,通过该流读取客   * 户端发送过来的请求信息并封装到当前HttpRequest对象中   */  public HttpRequest(InputStream in){  /* * HTTP协议中的请求信息格式: * 请求行       资源                    协议               换行 * GET/index.html  HTTP1.1 CRLF(请求方式) POST * 消息报头 * 消息正文 *  * 以行为单位发送至服务端 每行结尾以(CR LF) * CR:回车  LF:换行 * http://localhost:8080 */  try{      //读取一行字符串,请求行信息//Method Request-URI Http-version(CRLF)//如://GET/index.html HTTP/1.1CRLF String line=readline(in); if(line.length()>0){ String[] data=line.split("\\s"); method=data[0]; uri=data[1]; protocol=data[2]; }  }catch(IOException e){  e.printStackTrace();    }  }      /**   * 从给定的输入流中读取一行字符窜并返回。   * 当读取到CR LF时认为一行结束   *       13 10   *   * @param in   * @return   * @throws IOException   */  private String readline(InputStream in)throws IOException{/* * 顺序的从流中读取每个字节并转换为对应的字符 * 然后拼接在一起,直到连续读取了CR LF时停止 * 并将拼接的字符串返回 */  StringBuilder builder=new StringBuilder();  try{  int ch1=-1,ch2=-1;  while((ch2=in.read())!=-1){  if(ch1==HttpContent.CR&&ch2==HttpContent.LF){  break;  }  builder.append((char)ch2);  ch1=ch2;  }  return builder.toString().trim();  }catch(IOException e){  throw e;  }  }public String getMethod() {return method;}public String getUri() {return uri;}public String getProtocol() {return protocol;}  }


原创粉丝点击