简介:使用java的nio技术,实现简单的代理服务器,访问本地1234端口,把请求转发的tomcat8080端口,实现代理
使用过程:
1. 开启tomcat,确保访问127.0.0.1:8080端口有显示
2. 启动App.java的main运行
3. 然后访问127.0.0.1:1234端口
有三个java文件
App.java 启动main进程
Server.java 服务类,监听1234端口,开启代理
Proxy.java 代理类,实现请求转发,代理访问8080端口,返回请求结果
App.java
public class App {
public static void main(String[] args) throws Exception {
Server server = new Server(1234);
server.connection();
}
}
Server.java
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class Server {
private int port;
private SocketChannel remoteSocketChannel;
public Server(int port) {
this.port = port;
}
public void connection() throws Exception
{
System.out.println("start server listen...........");
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(this.port));
while(true){
SocketChannel socketChannel = serverSocketChannel.accept();
this.remoteSocketChannel=socketChannel;
System.out.println("get one conn:"+socketChannel);
ByteBuffer buf = ByteBuffer.allocate(10240);
buf.clear();
int len = socketChannel.read(buf);
System.out.println("read from client:"+len+" ..............");
Proxy client = new Proxy("localhost",8080,this);
ByteBuffer request = buf.duplicate();
request.rewind();
client.request(request);
buf.clear();
}
}
public void output(ByteBuffer buf) throws Exception
{
remoteSocketChannel.write(buf);
}
public void done() throws Exception
{
remoteSocketChannel.close();
}
}
Proxy.java
import java.io.Serializable;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
class Proxy {
private String proxyIp;
private int port;
private Server server;
public Proxy(String proxyIp, int port,Server server) {
this.proxyIp = proxyIp;
this.port = port;
this.server=server;
}
public void request(ByteBuffer buf) throws Exception {
System.out.println("start proxy conn........");
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress(this.proxyIp, this.port));
while (true) {
System.out.println("in proxy while.................");
if (socketChannel.isConnected()) {
System.out.println("proxy isConnected.............");
//发送http
int bytesWrite = socketChannel.write(buf);
buf.clear();
int read = 0;
ByteBuffer buffer = ByteBuffer.allocate(1024);
while ((read = socketChannel.read(buffer)) != -1) {
{
System.out.println("read from proxy:" + read + ".....................");
buffer.flip();
while (buffer.position() < buffer.limit()) {
//不能解析中文
// System.out.print((char) buffer.get());
//解析中文,不知道是否有个别乱码,缓存刚好截断utf8中文(三个字节)?
// System.out.println(Charset.forName("UTF-8").newDecoder().decode(buffer).toString());
server.output(buffer);
}
//#todo 需要计算body长度,缓存没满不一定读完数据,html文档没读完
if (buffer.limit() < buffer.capacity()) {
break;
}
buffer.clear();
}
}
}
socketChannel.close();
server.done();
break;
}
}
}