import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class NioClient {
//管道管理器
private Selector selector;
public NioClient init(String serverIp, int port) throws IOException{
//获取socket通道
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
//获得通道管理器
selector=Selector.open();
//客户端连接服务器,需要调用channel.finishConnect();才能实际完成连接。
channel.connect(new InetSocketAddress(serverIp, port));
//为该通道注册SelectionKey.OP_CONNECT事件
channel.register(selector, SelectionKey.OP_CONNECT);
return this;
}
public void listen() throws IOException{
System.out.println("客户端启动");
//轮询访问selector
while(true){
//选择注册过的io操作的事件(第一次为SelectionKey.OP_CONNECT)
selector.select();
Iterator<SelectionKey> ite = selector.selectedKeys().iterator();
while(ite.hasNext()){
SelectionKey key = ite.next();
//删除已选的key,防止重复处理
ite.remove();
if(key.isConnectable()){
SocketChannel channel=(SocketChannel)key.channel();
//如果正在连接,则完成连接
if(channel.isConnectionPending()){
channel.finishConnect();
}
channel.configureBlocking(false);
//向服务器发送消息
channel.write(ByteBuffer.wrap(getProxyStr().getBytes()));
//连接成功后,注册接收服务器消息的事件
channel.register(selector, SelectionKey.OP_READ);
System.out.println("客户端连接成功");
}else if(key.isReadable()){ //有可读数据事件。
SocketChannel channel = (SocketChannel)key.channel();
ByteBuffer buffer = ByteBuffer.allocate(500);
int len = channel.read(buffer);
if(len<=0)continue;
byte[] data = buffer.array();
String message = new String(data);
System.out.println("recevie message from server:, size:" + buffer.position() + " msg: " + message);
// ByteBuffer outbuffer = ByteBuffer.wrap(("client.".concat(msg)).getBytes());
// channel.write(outbuffer);
}
}
}
}
/**
* 发送代理头部信息
*/
private String getProxyStr(){
String host = "外网ip";
int port = 外网端口;
String _proxyUser = "代理用户名";
String _proxyPass = "代理密码";
/***********************************
* HTTP CONNECT protocol RFC 2616
***********************************/
String proxyConnect = "CONNECT " + host + ":" + port+" HTTP/1.1\r\n"+"host: "+host+":"+port+"\r\n\r\n";
// Add Proxy Authorization if proxyUser and proxyPass is set
try {
// String proxyUserPass = String.format("%s:%s", _proxyUser, _proxyPass);
// proxyConnect.concat(" HTTP/1.0\nProxy-Authorization:Basic " + Base64.encode(proxyUserPass.getBytes()));
} catch (Exception e) {
e.printStackTrace();
} finally {
proxyConnect.concat("\n\n");
}
// DefaultFullHttpRequest(decodeResult: success, version: HTTP/1.1, content: EmptyByteBufBE)
// CONNECT 210.21.237.137:15902 HTTP/1.1
// host: 210.21.237.137:15902
System.out.println(proxyConnect);
return proxyConnect;
}
public static void main(String[] args) throws IOException {
new NioClient().init("代理服务器ip", 代理服务port).listen();
}
}