Java Socket 實現HTTP服務器核心

原文連接:http://www.ihuxu.com/p/235.htmlhtml

 

首先了解下HTTP協議:java

wikiPedia的說明很好,在此不重複了。連接:http://zh.wikipedia.org/wiki/Http編程

 

源碼分析:服務器

概述:此兩個代碼段,完成服務器監聽,線程處理短請求服務和應答(符合僞HTTP協議,「僞」即判斷協議格式不嚴謹)。展現了利用java socket完成http通訊的核心原理代碼,但願給初次學習socket或者第一次利用java來實現HTTP協議服務器的朋友提供些幫助。網絡

 

利用 Java Socket 網絡編程來綁定服務器某個端口進行監聽。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 }  

 

說明:this

 

一、getValidRequest() 驗證請求消息是否知足僞HTTP協議。好比:GET /images/logo.gif HTTP/1.1,則會返回"/images/logo.gif"。若不符合僞HTTP協議或者請求時不發送任何消息頭(好比經過telnet訪問,此狀況最大延遲0.5秒),則會返回空串。spa

二、close(),釋放內存,同時線程結束。

三、run(),短請求的線程主體,在此處能夠進行數據邏輯處理,並返回特定消息內容。

相關文章
相關標籤/搜索