// 创建HTTP请求包处理线程
RequestThread request = new RequestThread(socket);
request.start();
if(shutdown) System.exit(0);
}
catch (Exception e) {
e.printStackTrace();
}
}
RequestThread线程分析HTTP请求包,跟根据请求包内容在服务端生成一个HTTP应答包。下一节说明怎样分析HTTP包。
InputStream input = socket.getInputStream(); //从此字节数据流获得HTTP请求包内容
OutputStream output= socket.getOutputStream(); //向此字节流写入HTTP应答包内容
三、读取HTTP包
以下我自己设计的一个读取HTTP包的类SocketRequest。
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) {
this.input = socket.getInputStream();
}
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\n
StringBuffer sb=new StringBuffer();
for(int i=(clIndex 16);;i )
{
if(requst[i]!=(byte)13 && requst[i]!=(byte)10 )
{
sb.append((char)requst[i]);
}
else
break;
}
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为头部结束
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




