NIOはクライアントで複数のサイトに同時にアクセスする


詳細
 
このdemoは、NIOがクライアントで複数のサイトに同時にアクセスする例を示しています.
同時にwww.kaola.を訪問しました.com,www.jd.com,www.tmall.com,www.suning.comという4つのサイトのトップページでは、印刷された情報から、総消費時間は最大suningの消費時間に依存することがわかります.
 
ue May 09 23:41:07 CST 2017[1494344467724],main,end...
Tue May 09 23:41:07 CST 2017[1494344467724],main,connecting  to www.kaola.com
Tue May 09 23:41:07 CST 2017[1494344467724],main,connecting  to www.jd.com
Tue May 09 23:41:07 CST 2017[1494344467724],main,connecting  to www.suning.com
Tue May 09 23:41:07 CST 2017[1494344467725],main,connecting  to www.tmall.com
Tue May 09 23:41:07 CST 2017[1494344467725],main,running...
Tue May 09 23:41:07 CST 2017[1494344467737],main, :www.kaola.com :13
Tue May 09 23:41:07 CST 2017[1494344467752],main, :www.jd.com :28
Tue May 09 23:41:07 CST 2017[1494344467752],main, :www.tmall.com :28
Tue May 09 23:41:07 CST 2017[1494344467781],main, :www.suning.com :57
56

 
/**
 * Desc:TODO
 * 
 * @author wei.zw
 * @since 2017 5 9   7:31:20
 * @version v 0.1
 */
public class HttpSocket {
	private Selector selector;
	private final Map startTimeMap = new HashMap<>();

	/**
	 * @param host
	 * @param port
	 */
	public HttpSocket() {
		super();

		try {
			selector = Selector.open();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	/**
	 * 
	 * 
	 * @author wei.zw
	 */
	public void start() {
		LogUitl.log("running...");
		long start = System.currentTimeMillis();

		while (startTimeMap.size() > 0) {
			try {
				selector.select(1);
				Set selectionKeys = selector.selectedKeys();
				Iterator it = selectionKeys.iterator();
				SelectionKey key = null;
				while (it.hasNext()) {
					key = it.next();
					it.remove();
					try {
						handleInput(key);
					} catch (Exception e) {
						if (key != null) {
							key.cancel();
							if (key.channel() != null) {
								key.channel().close();
							}
						}
					}
				}
			} catch (IOException e) {
				System.exit(1);
			}

		}
		System.out.println(System.currentTimeMillis() - start);
		// end
		if (selector != null) {
			try {
				LogUitl.log("close");
				selector.close();
			} catch (IOException e) {
				e.printStackTrace();
				System.exit(1);
			}
		}
		LogUitl.log("end...");

	}

	/**
	 *  
	 * @param key
	 * @author wei.zw
	 * @throws IOException
	 */
	private void handleInput(SelectionKey key) throws IOException {
		if (key.isValid()) {
			SocketChannel sc = (SocketChannel) key.channel();
			if (key.isConnectable()) {
				if (sc.finishConnect()) {
					String str = sc.getRemoteAddress().toString();
					String host = str.substring(0, str.indexOf("/"));
					doWrite(sc, host);
				} else {
					System.exit(1);
				}
			}
			if (key.isReadable()) {
				String str = sc.getRemoteAddress().toString();
				String host = str.substring(0, str.indexOf("/"));
				if (!startTimeMap.containsKey(host)) {
					return;
				}
				ByteBuffer readBuffer = ByteBuffer.allocate(1024);
				int readBytes = sc.read(readBuffer);
				if (readBytes > 0) {

					readBuffer.flip();
					byte[] bytes = new byte[readBuffer.remaining()];
					readBuffer.get(bytes);
					readBuffer.clear();
					// String body = new String(bytes, "UTF-8");
					// System.out.println(body);

					LogUitl.log(" :" + host + " :" + (System.currentTimeMillis() - startTimeMap.get(host)));
					startTimeMap.remove(host);
					// stop--;
				} else if (readBytes < 0) {
					key.cancel();
					sc.close();
				}
			}
		}
	}

	/**
	 *  SocketChannel  Selector SocketChannel  channel socket
	 * 
	 * @author wei.zw
	 * @throws IOException
	 */
	public void doHttpConnection(String host, int port) throws IOException {
		SocketChannel socketChannel = SocketChannel.open();
		socketChannel.configureBlocking(false);
		startTimeMap.put(host, System.currentTimeMillis());
		LogUitl.log("connecting  to " + host);
		socketChannel.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ);
		socketChannel.connect(new InetSocketAddress(InetAddress.getByName(host), port));
	}

	/**
	 * 
	 * @param socketChannel2
	 * @author wei.zw
	 * @throws IOException
	 */
	private void doWrite(SocketChannel socketChannel, String host) throws IOException {
		StringBuilder sb = new StringBuilder().append("GET / HTTP/1.1\r
").append("Host: " + host + " \r
") .append("\r
"); byte[] req = sb.toString().getBytes(); ByteBuffer writeBuffer = ByteBuffer.allocate(req.length); writeBuffer.put(req); writeBuffer.flip(); socketChannel.write(writeBuffer); if (!writeBuffer.hasRemaining()) { } } }