zoukankan      html  css  js  c++  java
  • Java Socket 实现HTTP服务器核心

    原文链接:http://www.ihuxu.com/p/235.html

     

    首先了解下HTTP协议:

    wikiPedia的说明很好,在此不重复了。链接:http://zh.wikipedia.org/wiki/Http

    源码分析:

    概述:此两个代码段,完成服务器监听,线程处理短请求服务和应答(符合伪HTTP协议,“伪”即判断协议格式不严谨)。展示了利用java socket完成http通信的核心原理代码,希望给初次学习socket或者第一次利用java来实现HTTP协议服务器的朋友提供些帮助。

    利用 Java Socket 网络编程来绑定服务器某个端口进行监听。

     1 package JHServer;  
     2   
     3 import java.io.IOException;  
     4 import java.net.ServerSocket;  
     5 import java.net.Socket;  
     6   
     7 public class Server {  
     8       
     9     private static int PORT = 1720;  
    10     public static String charset = "utf-8";  
    11     private ServerSocket ss;  
    12     private Socket client;  
    13   
    14     public static void main(String[] args) {  
    15         new Server();  
    16     }  
    17   
    18     public Server() {  
    19         try {  
    20             this.ss = new ServerSocket(this.PORT);  
    21 System.out.println("Server Listening Port " + this.PORT + "...");  
    22             boolean isGo = true;  
    23             while(isGo){  
    24                 this.client = this.ss.accept();  
    25 System.out.println("One Client Connected. " + this.client);  
    26                 ClientThread ct = new ClientThread(this.client);  
    27                 Thread t = new Thread(ct);  
    28                 t.start();  
    29 System.out.println("One Client Thread Already Started...");  
    30             }  
    31         } catch (IOException e) {  
    32             e.printStackTrace();  
    33         } finally {  
    34             try{  
    35                 if(this.ss != null){  
    36                     this.ss.close();  
    37                     this.ss = null;  
    38                 }  
    39                 if(this.client != null){  
    40                     this.client.close();  
    41                     this.client = null;  
    42                 }  
    43             } catch(IOException e) {  
    44                 e.printStackTrace();  
    45             }  
    46         }  
    47     }  
    48       
    49 }  

    说明:上述代码完成了服务端口(1720,你懂么)的监听,并同时利用线程了处理每个客户端(Client )的消息请求,以减少服务器处理”短请求“阻塞问题。

    下述代码完成请求是否符合伪HTTP协议,并完成响应消息。

      1 package JHServer;  
      2   
      3 import java.io.*;  
      4 import java.net.Socket;  
      5 import java.util.Date;  
      6   
      7 import action.ManagerEachMatchInfo;  
      8   
      9 import view.*;  
     10   
     11 public class ClientThread implements Runnable {  
     12   
     13     private float requestDelay = (float)0.5;//  
     14       
     15     private Socket _s;  
     16     private BufferedReader i;  
     17     private PrintStream o;  
     18   
     19     public ClientThread(Socket s) {  
     20         this._s = s;  
     21     }  
     22   
     23     public void run() {  
     24         try {  
     25             this.i = new BufferedReader(new InputStreamReader(this._s.getInputStream()));  
     26             this.o = new PrintStream(this._s.getOutputStream());  
     27   
     28             String request = this.getValidRequest();  
     29               
     30             if( !request.equals("") ) {  
     31                 System.out.print("当前虚拟机最大可用内存为:");     
     32                 System.out.println(Runtime.getRuntime().maxMemory()/1024/1024+"M");   
     33                 System.out.print("当前,虚拟机已占用内存:");    
     34                 System.out.println(Runtime.getRuntime().totalMemory()/1024/1024+"M");    
     35                 this.o.println("HTTP/1.1 200 OK");  
     36                 Date now = new Date();  
     37                 this.o.println("Data:" + now);  
     38                 this.o.println("Server: JHServer");  
     39                 this.o.println("Access-Control-Allow-Origin:*");  
     40   
     41                 this.o.println("Content-Type: text/html; charset=UTF-8");  
     42                 this.o.println();  
     43                 String content = null;  
     44                 IndeMatchInfo imi = new IndeMatchInfo(22,22,2,2,22,(double)0.0,"S7-200");  
     45                 content = imi.getHTML();  
     46                   
     47                 imi.clear();                  
     48                 imi = null;  
     49                 System.out.print("当前虚拟机最大可用内存为:");     
     50                 System.out.println(Runtime.getRuntime().maxMemory()/1024/1024+"M");   
     51                 System.out.print("当前,虚拟机已占用内存:");    
     52                 System.out.println(Runtime.getRuntime().totalMemory()/1024/1024+"M");    
     53   
     54                 this.o.println(content);  
     55                 content = "";  
     56                 this.o.flush();  
     57                     
     58             }  
     59   
     60         } catch (IOException e) {  
     61             e.printStackTrace();  
     62         } finally {  
     63             this.close();  
     64         }  
     65   
     66     }  
     67   
     68     private String getValidRequest() {  
     69   
     70         float second = (float) 0.0;  
     71         boolean isGo = true;  
     72         String request = null;  
     73         try {  
     74             while (!this.i.ready()) {  
     75                 second += 0.01;  
     76                 if (second > this.requestDelay) {  
     77                     System.out.println("One Client Delayed " + this._s);  
     78                     isGo = false;  
     79                     break;  
     80                 }  
     81                 Thread.sleep(10);  
     82             }  
     83   
     84             if (isGo == true) {  
     85                 request = this.i.readLine();  
     86                 if( request.contains("GET /") && request.contains(" HTTP/") ) {  
     87                     request = request.substring(request.indexOf("/"),request.indexOf(" HTTP/"));  
     88 System.out.println("Client Request Info: " + request);  
     89                 } else {  
     90                     isGo = false;  
     91                 }  
     92             }  
     93         } catch (InterruptedException e) {  
     94             e.printStackTrace();  
     95         } catch (IOException e) {  
     96             e.printStackTrace();  
     97         } finally {  
     98             if(isGo == true) {  
     99                 return request;  
    100             } else {  
    101                 return "null";  
    102             }  
    103         }  
    104     }  
    105   
    106     private void close() {  
    107         try {  
    108             if (this.i != null) {  
    109                 this.i.close();  
    110                 this.i = null;  
    111             }  
    112             if (this.o != null) {  
    113                 this.o.close();  
    114                 this.o = null;  
    115             }  
    116             if (this._s != null) {  
    117                 this._s.close();  
    118                 this._s = null;  
    119             }  
    120 System.out.println("One Client Disconnected...");  
    121         } catch (IOException e) {  
    122             e.printStackTrace();  
    123         }  
    124     }  
    125   
    126 }  

    说明:

    1、getValidRequest() 验证请求消息是否满足伪HTTP协议。比如:GET /images/logo.gif HTTP/1.1,则会返回"/images/logo.gif"。若不符合伪HTTP协议或者请求时不发送任何消息头(比如通过telnet访问,此情况最大延迟0.5秒),则会返回空串。

    2、close(),释放内存,同时线程结束。

    3、run(),短请求的线程主体,在此处可以进行数据逻辑处理,并返回特定消息内容。

  • 相关阅读:
    mac zsh选择到行首的快捷键
    phalcon下拉列表
    tinycore remaster方法
    bundle安装方法
    centos7安装avahi
    pydoc介绍
    macosx下apache的默认用户为daemon
    centos配置ssh免密码登录后,仍提示输入密码
    xampp默认项目文件夹htdocs
    微信开发:"errcode": -1000,"errmsg": "system error"错误的解决办法
  • 原文地址:https://www.cnblogs.com/wuniaoheart/p/3593627.html
Copyright © 2011-2022 走看看