原文链接: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(),短请求的线程主体,在此处可以进行数据逻辑处理,并返回特定消息内容。
Java Socket 实现HTTP服务器核心,布布扣,bubuko.com
原文:http://www.cnblogs.com/wuniaoheart/p/3593627.html