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 网络编程来绑定服务器某个端口进行监听。

 

[java]  view plain copy 在CODE上查看代码片
 
  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协议,并完成响应消息。

 

[java]  view plain copy 在CODE上查看代码片
 
  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 = (float0.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(),短请求的线程主体,在此处可以进行数据逻辑处理,并返回特定消息内容。

你可能感兴趣的:(java,http,socket)