java实现轻量型http代理服务器示例
packagecn.liangjintang.httpproxy;
importjava.io.BufferedReader;
importjava.io.ByteArrayInputStream;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.InputStreamReader;
importjava.io.OutputStream;
importjava.net.ServerSocket;
importjava.net.Socket;
publicclassHttpProxy{
staticlongthreadCount=0;
intmyTcpPort=8080;
privateServerSocketmyServerSocket;
privateThreadmyThread;
publicHttpProxy(intport)throwsIOException{
myTcpPort=port;
myServerSocket=newServerSocket(myTcpPort);
myThread=newThread(newRunnable(){
publicvoidrun(){
try{
while(true)
newHTTPSession(myServerSocket.accept());
}catch(IOExceptionioe){
}
}
});
myThread.setDaemon(true);
myThread.start();
}
/**
*Stopstheserver.
*/
publicvoidstop(){
try{
myServerSocket.close();
myThread.join();
}catch(IOExceptionioe){
}catch(InterruptedExceptione){
}
}
publicclassHTTPSessionimplementsRunnable{
privateSocketmySocket;
publicHTTPSession(Sockets){
mySocket=s;
Threadt=newThread(this);
t.setDaemon(true);
t.start();
}
@Override
publicvoidrun(){
try{
++threadCount;
InputStreamis=mySocket.getInputStream();
if(is==null)
return;
finalintbufsize=8192;
byte[]buf=newbyte[bufsize];
intsplitbyte=0;
intrlen=0;
{
intread=is.read(buf,0,bufsize);
while(read>0){
rlen+=read;
splitbyte=findHeaderEnd(buf,rlen);
if(splitbyte>0)
break;
read=is.read(buf,rlen,bufsize-rlen);
}
ByteArrayInputStreamhbis=newByteArrayInputStream(buf,
0,rlen);
BufferedReaderhin=newBufferedReader(
newInputStreamReader(hbis));
Hosthost=newHost();
{
Stringstring;
booleanflag=false;
while((string=hin.readLine())!=null){
if(string.toLowerCase().startsWith("host:")){
host.host=string;
flag=true;
}
System.out.println(string);
}
if(!flag){
mySocket.getOutputStream().write(
"error!".getBytes());
mySocket.close();
return;
}
}
host.cal();
System.out.println("address:["+host.address+"]port:"
+host.port+"\n-------------------\n");
try{
pipe(buf,rlen,mySocket,mySocket.getInputStream(),
mySocket.getOutputStream(),host);
}catch(Exceptione){
System.out.println("RunException!");
e.printStackTrace();
}
}
}catch(Exceptione){
}
System.out.println("threadcount:"+--threadCount);
}
/**
*finadhttpheader
**/
privateintfindHeaderEnd(finalbyte[]buf,intrlen){
intsplitbyte=0;
while(splitbyte+3<rlen){
if(buf[splitbyte]=="\r"&&buf[splitbyte+1]=="\n"
&&buf[splitbyte+2]=="\r"
&&buf[splitbyte+3]=="\n")
returnsplitbyte+4;
splitbyte++;
}
return0;
}
voidpipe(byte[]request,intrequestLen,Socketclient,
InputStreamclientIS,OutputStreamclientOS,Hosthost)
throwsException{
bytebytes[]=newbyte[1024*32];
Socketsocket=newSocket(host.address,host.port);
socket.setSoTimeout(3000);
OutputStreamos=socket.getOutputStream();
InputStreamis=socket.getInputStream();
try{
do{
os.write(request,0,requestLen);
intresultLen=0;
try{
while((resultLen=is.read(bytes))!=-1
&&!mySocket.isClosed()&&!socket.isClosed()){
clientOS.write(bytes,0,resultLen);
}
}catch(Exceptione){
System.out.println("targetSocketexception:"
+e.toString());
}
System.out.println("proxyrequset-connectbroken,socket:"
+socket.hashCode());
}while(!mySocket.isClosed()
&&(requestLen=clientIS.read(request))!=-1);
}catch(Exceptione){
System.out.println("clientSocketexception:"+e.toString());
}
System.out.println("end,socket:"+socket.hashCode());
os.close();
is.close();
clientIS.close();
clientOS.close();
socket.close();
mySocket.close();
}
//targetHostinfo
finalclassHost{
publicStringaddress;
publicintport;
publicStringhost;
publicbooleancal(){
if(host==null)
returnfalse;
intstart=host.indexOf(":");
if(start==-1)
returnfalse;
intnext=host.indexOf(":",start+2);
if(next==-1){
port=80;
address=host.substring(start+2);
}else{
address=host.substring(start+2,next);
port=Integer.valueOf(host.substring(next+1));
}
returntrue;
}
}
}
publicstaticvoidmain(String[]args){
try{
newHttpProxy(8580);
}catch(IOExceptionioe){
System.err.println("Couldn"tstartserver:\n"+ioe);
System.exit(-1);
}
System.out.println("start!");
try{
System.in.read();
}catch(Throwablet){
}
System.out.println("stop!");
}
}
相关文章
- Java详解:淘宝秒杀脚本java
- java反转数组_Java实现数组反转翻转的方法实例
- java scanner怎么用_Java中Scanner类的用法及使用步骤分享!「建议收藏」
- java如何输入字符串_JAVA中怎样输入字符串「建议收藏」
- Java生成随机数组_java生成唯一数字
- java 标准输出与标准错误 out与 err 区别 用法 联系 java中的out与err区别 System.out和System.err的区别 System.out.println和System.err.println的区别 Java重定向System.out和System.err详解编程语言
- 请求使用Linux发送HTTP请求的方法(linux发送http)
- Java内部类总结详解编程语言
- Java监控MySQL性能:实现数据库运行优化(java监控mysql)
- Linux调用Java实现编程快速开发(linux调用java)
- Java编程实现MySQL表备份(java备份mysql表)
- Java驾驭MySQL,读写如飞(java读写mysql)
- 管理Linux下Java版本管理:轻松实现多版本切换(linux下java版本)
- Linux上善用Java:实现智能开发(linux 运行java)
- Java解答Oracle使用更轻松的实现方式(oracle写成java)
- Java锁表与Oracle数据库协调实现数据安全(java锁表oracle)
- Java模拟Oracle实现稳定数据库性能(java模仿oracle)