http代理工作原理(2)
我们那个邮局里面的工作人员很笨,不识字,导致我们还要借助更强大的邮局才能完成我们的工作,现在我们打算让他学点文化知识,这样以后我们就不需要Fiddler了.前面已经说过,在信封的第一行也就是HTTP协议的第一行写的就是收件人的地址,那么我们这个工作人员只需要把它读出来,并按照这个地址发出去就可以了,接下来的工作就是让这个工作人员读出这个地址。
第一步,先给这个工作人员增加一项技能,就是读取一行的技能,在具体的类里面我们定义为一个方法:
[java]
private static byte[] readLine(InputStream stream) throws IOException
{
int b = -1;
ByteArrayOutputStream bos = new ByteArrayOutputStream(2048);
while((b = stream.read()) != -1)
{
if(b == '\n')
{
bos.write(b);
break;
}
bos.write(b);
}
return bos.toByteArray();
}
然后,当有信件到达的时候,这个工作人员先读取第一行,这样他就可以知道信件是要发给谁了:
[java]
/**
* 读取协议头的第一行
* 格式: GET http://www.mytest.com HTTP/1.1
*/
byte[] buffer = readLine(inputStream);
if(buffer.length < 1)
{
return;
}
String header = new String(buffer, "UTF-8");
String[] action = header.split(" ");
if(action.length < 3)
{
return;
}
String address = action[1];
/**
* 目标地址是从http协议的第一行取
* 目标主机应该从协议的Host头里面取,如果Host取不到, 从地址里面取
* 此处为了简化逻辑只从地址里面取host, 因此如果路径不是绝对路径就忽略
*/
if(address.startsWith("http://") == false)
{
return;
}
System.out.print(header);
URL url = new URL(address);
String host = url.getHost();
int port = (url.getPort() > -1 ? url.getPort() : 80);
remote = new Socket(host, port);
接下来的代码就跟前面一样了,参考上篇。
下面是完整的代码:
[java]
/*
* $RCSfile: SimpleHttpProxy2.java,v $$
* $Revision: 1.1 $
* $Date: 2013-1-14 $
*
* Copyright (C) 2008 Skin, Inc. All rights reserved.
*
* This software is the proprietary information of Skin, Inc.
* Use is subject to license terms.
*/
package test.com.skin.http.proxy;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* <p>Title: SimpleHttpProxy2</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2006</p>
* @author xuesong.net
* @version 1.0
*/
public class SimpleHttpProxy2
{
public static final int PORT = 6666;
public static final byte[] CRLF = new byte[]{0x0D, 0x0A};
/**
* @param args
*/
public static void main(String[] args)
{
ServerSocket socketServer = null;
BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(1024);
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(512, 1024, 30000, TimeUnit.SECONDS, blockingQueue);
try
{
socketServer = new ServerSocket(PORT);
while(true)
{
try
{
final Socket socket = socketServer.accept();
Runnable job = new Runnable(){
public void run(){
service(socket);
}
};
threadPoolExecutor.execute(job);
}
catch(SocketTimeoutException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
catch(Exception e)
{
补充:软件开发 , Java ,
上一个:http代理工作原理(3)
下一个:http代理工作原理(1)
- 更多JAVA疑问解答:
- java怎么在线读取ftp服务器上的文件内容
- 关于程序员的职业规划
- HTML和JSP矛盾吗?
- java小程序如何打包?
- java怎么split路径文件名?
- jsp+javaBean中Column 'ordersPrice' specified twice的错误
- Java TCP/IP Socket网络编程系列
- 大家来讨论一下我到底该用什么好?Swing 还是 JavaFX
- 关于Hibernate实体自身多对一的抓取问题
- 关于apache2+tomcat群集出现的问题
- spring 获取上下文问题
- SSH 导入导出excel 谁有这块的资料吗?
- Ext TreePanel 刷新问题
- springmvc 加载一个jsp页面执行多个方法 报404
- checkbox数组action怎么向页面传值