`
zhangwei_david
  • 浏览: 477224 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

NIO在客户端并发访问多个站点

    博客分类:
  • NIO
阅读更多

 

    这个demo演示了NIO在客户端并发访问多个站点的示例:

同时访问了 www.kaola.com,www.jd.com,www.tmall.com,www.suning.com这个四个站点的首页,通过打印的信息可以发现总耗时取决于最大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<String, Long> 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<SelectionKey> selectionKeys = selector.selectedKeys();
				Iterator<SelectionKey> 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\n").append("Host: " + host + " \r\n")
				.append("\r\n");
		byte[] req = sb.toString().getBytes();
		ByteBuffer writeBuffer = ByteBuffer.allocate(req.length);
		writeBuffer.put(req);
		writeBuffer.flip();
		socketChannel.write(writeBuffer);

		if (!writeBuffer.hasRemaining()) {

		}
	}

}

 

0
1
分享到:
评论

相关推荐

    一个java写的FTP搜索引擎

    - 为了提高搜索效率,搜索引擎可能使用多线程技术,同时处理多个FTP连接或搜索任务。 - `java.util.concurrent`包提供了一系列工具类,如`ExecutorService`,便于管理和调度并发任务。 8. **性能优化**: - 为...

    java开源包1

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    视频聊天系统全代码附数据库

    4. **服务器架构**:服务器端可能采用多线程或多进程处理客户端请求,也可能使用事件驱动或异步I/O模型(如Node.js的Event Loop或Java的NIO)来提高并发性能。 5. **信号控制**:视频聊天系统需要实现信令机制,...

    java开源包11

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包2

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包3

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包6

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包5

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包10

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包4

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包8

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包7

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包9

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包101

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    Java资源包01

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    apache-tomcat-7.0.26 32bit/64bit 安装版本

    - **Common, Server, Shared Libraries**:这些目录用于存放可以被多个Web应用共享的JAR文件,不同目录代表加载的时机不同。 此外,Tomcat 7.0.26版本还支持以下特性: - **JSP 2.2** 和 **Servlet 3.0** 规范,...

    Tomcat 7.0

    8. **虚拟主机(Virtual Hosts)**:通过配置`server.xml`中的`&lt;Host&gt;`元素,可以在同一台Tomcat服务器上部署多个独立的Web站点。 9. **热部署**:当Web应用的类或资源发生改变时,Tomcat可以自动检测并重新加载,...

    kftpserver:java开发的一个简单的ftp服务器

    每个客户端连接都会被分配一个独立的线程来处理,确保服务器可以并发地响应多个请求。 4. **FTP协议**:FTP协议包括一系列的命令和响应,如USER(用户认证)、PASS(密码认证)、LIST(列出目录内容)、RETR(下载...

    JAVA网络编程从入门到精通

    - **`Selector`**:用于监控多个通道的就绪状态。 - **`Channel`**:用于读写数据的通道。 #### 二十七、非阻塞I/O的缓冲区 `Buffer`类用于存储和操作数据。 - **常用方法**:`flip()`、`clear()`、`compact()`等...

Global site tag (gtag.js) - Google Analytics