利用NIO非阻塞方式制作浏览器代理
下面代码的大致思路是:传入一个socketServer得到的socket的,然后再建立一条到其他代理服务器的socket的,接着就是按照顺序来回倒数据,只要读入的数据不是-1,那么就有可能再读到数据,这2条通路的任何一条通路读入数据为-1,那么就结束。其次还有退出循环的可能就是,在读数据的时候发生异常,有2种情况会产生这种异常,要么浏览器认为没有数据可以读了,要么代理服务器那里认为没有数据可以写过来了,那么它们就会close它们各自的socket,此时我们再尝试读socket,就会报错:socket已经被断开。
- import java.io.IOException;
- import java.net.InetSocketAddress;
- import java.nio.ByteBuffer;
- import java.nio.channels.SocketChannel;
- import java.nio.charset.Charset;
- /**
- * 提供一种非阻塞方式的网络连接,性能提高
- */
- public class SocketNioHandler {
- private InetSocketAddress endpoint;
- public SocketNioHandler() {
- }
- public SocketNioHandler(InetSocketAddress endpoint) {
- this.endpoint = endpoint;
- }
- /**
- * 此方法是线程安全的
- */
- @Override
- public boolean process(SocketChannel socket) {
- SocketChannel outSocket = null;
- ByteBuffer buff = ByteBuffer.allocate(1024);
- try {
- outSocket = SocketChannel.open(endpoint);
- outSocket.configureBlocking(false);
- while (true) {
- if (socket.read(buff) < 0) {
- break;
- } else {
- buff.flip();
- if (buff.limit() > 10)
- System.out.println(Charset.defaultCharset()
- .decode(buff));
- buff.rewind();
- while (buff.remaining() != 0) {
- outSocket.write(buff);
- }
- buff.clear();
- }
- if (outSocket.read(buff) < 0) {
- break;
- } else {
- buff.flip();
- while (buff.remaining() != 0) {
- socket.write(buff);
- }
- buff.clear();
- }
- try {
- Thread.sleep(1);
- } catch (InterruptedException e) {
- ;
- }
- }
- } catch (IOException e) {
- ;
- } finally {
- try {
- socket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- outSocket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return true;
- }
- }