java实现轻量型http代理服务器示例
发布时间:2021-10-05 18:14:20
package cn.liangjintang.httpproxy;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class HttpProxy {
static long threadCount = 0;
int myTcpPort = 8080;
private ServerSocket myServerSocket;
private Thread myThread;
public HttpProxy(int port) throws IOException {
myTcpPort = port;
myServerSocket = new ServerSocket(myTcpPort);
myThread = new Thread(new Runnable() {
public void run() {
try {
while (true)
new HTTPSession(myServerSocket.accept());
} catch (IOException ioe) {
}
}
});
myThread.setDaemon(true);
myThread.start();
}
/**
* Stops the server.
*/
public void stop() {
try {
myServerSocket.close();
myThread.join();
} catch (IOException ioe) {
} catch (InterruptedException e) {
}
}
public class HTTPSession implements Runnable {
private Socket mySocket;
public HTTPSession(Socket s) {
mySocket = s;
Thread t = new Thread(this);
t.setDaemon(true);
t.start();
}
@Override
public void run() {
try {
++threadCount;
InputStream is = mySocket.getInputStream();
if (is == null)
return;
final int bufsize = 8192;
byte[] buf = new byte[bufsize];
int splitbyte = 0;
int rlen = 0;
{
int read = 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);
}
ByteArrayInputStream hbis = new ByteArrayInputStream(buf,
0, rlen);
BufferedReader hin = new BufferedReader(
new InputStreamReader(hbis));
Host host = new Host();
{
String string;
boolean flag = 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 (Exception e) {
System.out.println("Run Exception!");
e.printStackTrace();
}
}
} catch (Exception e) {
}
System.out.println("threadcount:" + --threadCount);
}
/**
* finad http header
**/
private int findHeaderEnd(final byte[] buf, int rlen) {
int splitbyte = 0;
while (splitbyte + 3 < rlen) {
if (buf[splitbyte] == '\r' && buf[splitbyte + 1] == '\n'
&& buf[splitbyte + 2] == '\r'
&& buf[splitbyte + 3] == '\n')
return splitbyte + 4;
splitbyte++;
}
return 0;
}
void pipe(byte[] request, int requestLen, Socket client,
InputStream clientIS, OutputStream clientOS, Host host)
throws Exception {
byte bytes[] = new byte[1024 * 32];
Socket socket = new Socket(host.address, host.port);
socket.setSoTimeout(3000);
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
try {
do {
os.write(request, 0, requestLen);
int resultLen = 0;
try {
while ((resultLen = is.read(bytes)) != -1
&& !mySocket.isClosed() && !socket.isClosed()) {
clientOS.write(bytes, 0, resultLen);
}
} catch (Exception e) {
System.out.println("target Socket exception:"
+ e.toString());
}
System.out.println("proxy requset-connect broken,socket:"
+ socket.hashCode());
} while (!mySocket.isClosed()
&& (requestLen = clientIS.read(request)) != -1);
} catch (Exception e) {
System.out.println("client Socket exception:" + e.toString());
}
System.out.println("end,socket:" + socket.hashCode());
os.close();
is.close();
clientIS.close();
clientOS.close();
socket.close();
mySocket.close();
}
// target Host info
final class Host {
public String address;
public int port;
public String host;
public boolean cal() {
if (host == null)
return false;
int start = host.indexOf(": ");
if (start == -1)
return false;
int next = 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));
}
return true;
}
}
}
public static void main(String[] args) {
try {
new HttpProxy(8580);
} catch (IOException ioe) {
System.err.println("Couldn't start server:\n" + ioe);
System.exit(-1);
}
System.out.println("start!");
try {
System.in.read();
} catch (Throwable t) {
}
System.out.println("stop!");
}
}
猜你喜欢
- 最近想关闭一个包的日志打印,经过一番研究实际上就一句话的事,一直没成功是因为name写错了。<logger name="pa
- 一、结构型模式结构型模式有什么好处?从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题二、适配器模式USB网线转换器三、
- 一、why(为什么要用Hibernate缓存?)Hibernate是一个持久层框架,经常访问物理数据库。为了降低应用程序对物理数据源访问的频
- 程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间
- 前端页面功能模块化拆分当一个系统的功能很多时,不可能所有功能模块的页面都写在一个页面里面,这时就需要将不同功能模块的页面拆分出去,就像模板一
- springboot项目启动慢的问题排查springboot项目,随着时间的推移,启动耗时逐步增加,从几分钟慢慢的达到30多分钟,有点恐怖!
- 前言:各位小伙伴们,大家好,一日不见,如隔一日,今天我给大家分享一下大家在学习java过程当中遇到的一个问题,也是一道面试题,java中,O
- 本文实例讲述了Java使用Preference类保存上一次记录的方法。分享给大家供大家参考。具体分析如下:在使用java中JFileChoo
- 一.内容抽象类当编写一个类时,常常会为该类定义一些方法,这些方法用于描述这个类的行为。但在某些情况下只需要定义出一些方法,而不需要具体的去实
- 题目要求思路一:暴力模拟由于数据范围不算离谱,所以直接遍历解决可行。Javaclass Solution { pu
- 导入redis的jar包<!-- redis --> <dependency>  
- 注解从java5开始加入这一特性,发展到现在已然是遍地开花,在很多框架中得到了广泛的使用,用来简化程序中的配置。那充满争议的类型注解究竟是什
- 本人一直使用的是Eclipse作为开发工具的,不过现在IDEA非常的受推崇,所以决定上手试一试。网上有很多旗舰版的文章,我没有仔细看,我这次
- 1. 添加maven依赖包<dependency> <groupId>org.apache.calcit
- 因为涉及到 io 流输入问题,如果不关闭会一直占用资源。所以使用过后要及时关闭,防止资源一直被占用。Scanner在使用前要导入 java.
- 在项目中遇到try...catch...语句,因为对Java异常处理机制的流程不是很清楚,导致对相关逻辑代码不理解。所以现在来总结Java异
- 不论是float 还是double都是浮点数,而计算机是二进制的,浮点数会失去一定的精确度。Java在java.math包中提供的API类B
- 一、Mybatis1、mybatis-config.xml<?xml version="1.0" encoding
- 1. 概述官方JavaDocsApi: java.awt.FlowLayoutFlowLayout,流式布局管理器。按水平方向依次排列放置组
- 前言传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop、事物,这么做有两个缺点:1、如果所有的内容都配置在.xml