import java.io.IOException;import java.io.InputStream;import java.net.Socket;public class SocketRequest { // 從指定的Socket的InputStream中讀取資料private InputStream input;private String uri;private StringBuffer request = new StringBuffer(); // 用於儲存所有內容private int CONTENT_LENGTH = 0; // 實際包內容資料長private boolean bePost = false;private boolean beHttpResponse = false;private boolean beChucked = false;private boolean beGet = false;private byte crlf13 = (byte) 13; // '\r'private byte crlf10 = (byte) 10; // '\n'public SocketRequest(InputStream input) {this.input = input;}public SocketRequest(Socket socket) {try {this.input = socket.getInputStream();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void ReadData() { // 解析 獲得InputStream的資料ReadHeader(); // 頭部if (beChucked) // 為Chucked{int ChuckSize = 0;while ((ChuckSize = getChuckSize()) > 0) // 多個Chucked{readLenData(ChuckSize + 2);// 讀取定長資料}readLenData(2); // 最後的2位}if (CONTENT_LENGTH > 0) {readLenData(CONTENT_LENGTH);// 讀取定長資料}uri = "";// parseUri(new String(request));}private void readLenData(int size) // 讀取定長資料{int readed = 0; // 已經讀取數try {int available = 0;// input.available(); //可讀數if (available > (size - readed))available = size - readed;while (readed < size) {while (available == 0) { // 等到有資料可讀available = input.available(); // 可讀數}if (available > (size - readed))available = size - readed; // size-readed--剩餘數if (available > 2048)available = 2048; // size-readed--剩餘數byte[] buffer = new byte[available];int reading = input.read(buffer);request = request.append(new String(buffer, 0, reading)); // byte數組相加readed += reading; // 已讀字元}} catch (IOException e) {System.out.println("Read readLenData Error!");}}private void ReadHeader() // 讀取頭部 並獲得大小{byte[] crlf = new byte[1];int crlfNum = 0; // 已經串連的斷行符號換行數 crlfNum=4為頭部結束try {while (input.read(crlf) != -1) // 讀取頭部{if (crlf[0] == crlf13 || crlf[0] == crlf10) {crlfNum++;} else {crlfNum = 0;} // 不是則清request = request.append(new String(crlf, 0, 1)); // byte數組相加if (crlfNum == 4)break;}} catch (IOException e) {System.out.println("Read Http Header Error!");return;}String tempStr = (new String(request)).toUpperCase();// 這裡我只處理了GET與POST方法String strMethod = tempStr.substring(0, 4);if (strMethod.equals("GET ")) // 前{beGet = true;} else if (strMethod.equals("POST")) {bePost = true;getContentlen_Chucked(tempStr);} else {System.out.println("不支援的HTTP包類型");} // 其它的其它類型 暫不支援}private void getContentlen_Chucked(String tempStr) // 獲得長度 CONTENT-LENGTH 或// 是否為CHUNKED型{String ss1 = "CONTENT-LENGTH:";String ss2 = new String("TRANSFER-ENCODING: CHUNKED");int clIndex = tempStr.indexOf(ss1);int chuckIndex = tempStr.indexOf(ss2); // 為CHUNKED型byte requst[] = tempStr.getBytes();if (clIndex != -1) { // 從clIndex+1起至\r\nStringBuffer sb = new StringBuffer();for (int i = (clIndex + 16);; i++) {if (requst[i] != (byte) 13 && requst[i] != (byte) 10) {sb.append((char) requst[i]);} elsebreak;}CONTENT_LENGTH = Integer.parseInt(sb.toString()); // 正式的HTML檔案的大小// System.out.println("CONTENT_LENGTH== "+CONTENT_LENGTH);}if (chuckIndex != -1)beChucked = true;}private int getChuckSize() // Chuck大小{byte[] crlf = new byte[1];StringBuffer sb1 = new StringBuffer();int crlfNum = 0; // 已經串連的斷行符號換行數 crlfNum=4為頭部結束try {while (input.read(crlf) != -1) // 讀取頭部{if (crlf[0] == crlf13 || crlf[0] == crlf10) {crlfNum++;} else {crlfNum = 0;} // 不是則清sb1.append((char) crlf[0]);request = request.append(new String(crlf, 0, 1)); // byte數組相加if (crlfNum == 2)break;}} catch (IOException e) {System.out.println("Read Http Package Error!");return 0;}return Integer.parseInt((sb1.toString()).trim(), 16); // 16進控制}// 通過此來進行過濾,是否為發至目標伺服器的HTTP包private String parseUri(String requestString) {int index1, index2;index1 = requestString.indexOf(' ');if (index1 != -1) {index2 = requestString.indexOf(' ', index1 + 1);if (index2 > index1)return requestString.substring(index1 + 1, index2);}return null;}public String getData() {return request.toString();}}
網上找到的一篇,網上真正的原始碼解析的實在是少,只有虛擬碼以及php的,這個是java的,寫得很不錯。是轉載的哈。我就發上來了:
來自:http://www.cnblogs.com/fengmk2/articles/532777.html