`
yangyi
  • 浏览: 115701 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

NIO Web服务器示例

阅读更多
1 根据cpu core数量确定worker数量
2 selector服务accept和read
3 accept selector作为生产者把获得的请求放入队列
4 当获得read信号时,selector建立工作任务线程worker,并提交给系统线程池
5 worker线程排队后在线程池中执行,把协议头读入缓冲区,然后解析,处理,响应,关闭连接
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.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class WebServer {
    private static WebServer svr = new WebServer();
    private WebServer(){}
    public static WebServer getInstance(){return svr;}

    public void init() throws Exception{
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.configureBlocking(false);
        Selector sel = Selector.open();
        ssc.socket().bind(new InetSocketAddress(8088));
        ssc.register(sel, SelectionKey.OP_ACCEPT);
        ExecutorService es = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

        while (sel.isOpen()) {
            sel.select();
            Set<SelectionKey> readyKeys = sel.selectedKeys();
            Iterator<SelectionKey> iter = readyKeys.iterator();

            while (iter.hasNext()) {
                SelectionKey sk = iter.next();
                iter.remove();

                try{
                    if(!sk.isValid()){
                        continue;
                    }else if (sk.isAcceptable()) {
                        SocketChannel sc = ssc.accept();
                        sc.configureBlocking(false);
                        sc.register(sel, SelectionKey.OP_READ).attach(new Worker(sc));
                    }else if (sk.isReadable()) {
                        Worker worker = (Worker)sk.attachment();
                        if(worker.tryRunning()){
                            es.execute(worker);
                        }
                    }
                }catch(Exception ex){
                    System.err.println(sk.channel());
                    ex.printStackTrace();
                }
            }
        }
    }

    private static class Worker implements Runnable{
        private ByteBuffer bb = ByteBuffer.allocateDirect(1024);
        private SocketChannel sc = null;
        private State state = State.IDLE;

        private static enum State{
            IDLE, RUNNING
        }

        public Worker(SocketChannel sc){
            Thread.currentThread().setName(sc.toString());
            this.sc = sc;
        }
        private void dispose() throws IOException{
            sc.read(bb);
            bb.flip();
            byte[] bs = new byte[bb.limit()];
            bb.get(bs);
            System.err.println(sc);
            System.err.println(new String(bs));
            bb.clear();

            StringBuilder sb = new StringBuilder();
            sb.append("HTTP/1.1 200 OK").append("\n").append("Date:" + new Date()).append("\n");
            sb.append("Server:NIO Server By Aaron Yang\n\n");
            bb.put(sb.toString().getBytes());
            bb.put(
            "<html><head><script></script></head><body><div><h1>Hello World</h1></div></body></html>"
                .getBytes());

            bb.flip();
            sc.write(bb);
            bb.clear();

            sc.close();
        }

        public synchronized boolean tryRunning(){
            if(state == State.IDLE){
                state = State.RUNNING;
                return true;
            }
            return false;
        }

        public void run() {
            try {
                dispose();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        WebServer server = WebServer.getInstance();
        server.init();
    }
}   

===============06/27/10
如何解析header?,以行为单位读取,按照header敏感的关键字进行匹配 对于首行取得对方调用的方法GET/POST 地址 和协议版本
然后根据用户的配置,和解析地址请求,获得响应的servlet,并把通过反射+默认构造函数构造这个servlet,解析地址参数等设置到对象httpservletrequest和httpservletresponse中,然后通过反射invoke对应的get/post/put/delete等方法,并把封装的两个对象作为参数传进去,同时在response的header中传递一个cookie作为session的依据。
分享到:
评论

相关推荐

    Java NIO测试示例

    在实际应用中,Java NIO通常用于高性能的服务器编程,例如在开发聊天服务器、Web服务器或游戏服务器时,可以利用其高效的并发处理能力。然而,NIO的API相对复杂,学习曲线较陡峭,需要花费一定时间去理解和实践。...

    c++实现向web服务器上传文件

    本文将深入探讨如何使用C++实现向Web服务器上传文件,特别是在VS2013环境下,以及与Java Web工程的交互。 首先,我们要了解HTTP协议中的POST方法。在Web应用中,POST请求常用于提交数据到服务器进行处理,例如当...

    小型Web服务器实现

    【标题】"小型Web服务器实现"涉及的主要知识点是构建一个简单的网络服务器,特别是Web服务器的基础原理和编程实践。Web服务器是互联网基础设施的关键组成部分,用于接收HTTP请求并返回HTML页面或其他资源,如图片、...

    使用Java_NIO编写高性能的服务器.doc

    例如,像Tomcat这样的Web服务器就是基于这种方式来实现的。 - **线程池的使用**:为了防止线程无限制的增长,通常会使用线程池技术来限制同时运行的线程数量,从而减轻资源压力。 - **并发处理的局限性**:当达到...

    web容器示例程序

    接着是Jetty,它同样是一个轻量级的Web服务器和Servlet容器。Jetty以其高效、小巧和可嵌入性著称,常用于嵌入式系统和云计算环境。与Tomcat不同,Jetty支持非阻塞I/O(NIO),在处理高并发场景时,能更有效地利用...

    多线程web服务器 附实验报告 java

    以下是一个简单的多线程Web服务器示例,展示了如何通过ServerSocket接收连接,并为每个连接创建一个新线程: ```java ServerSocket server = new ServerSocket(8080); // 监听8080端口 while (true) { Socket ...

    基于多线程的web服务器

    在IT领域,Web服务器是互联网基础设施的核心组成部分,它们负责...在"基于多线程的WEB服务器.pos"这个文件中,可能包含了进一步的实现细节、代码示例或者性能分析,这些内容有助于深入理解多线程Web服务器的内部运作。

    js调用本地摄像头拍照并上传到web服务器

    综上所述,实现"js调用本地摄像头拍照并上传到web服务器"的功能,前端需要利用HTML5的API访问摄像头并捕获图像,然后将图片数据发送到服务器;后端则需要设置一个接收图片的接口,处理并存储上传的文件。在这个过程...

    Servlet API 和 NIO: 最终组合在一起

    Servlet API和NIO的结合主要体现在现代Web服务器的设计中。例如,Tomcat服务器在处理请求时就结合了Servlet API和NIO。当一个HTTP请求到达时,Tomcat会使用Servlet API解析请求,然后通过NIO模型将请求传递给后端...

    NIOHTTPServer:带有 JDK 的 NIO 示例 HTTP 服务器

    带有 JDK 的 NIO 示例 HTTP 服务器 使用以下命令也使用 Maven build 构建项目 mvn clean install 使用以下 Maven 构建命令构建具有依赖库的项目 mvn clean assembly:assembly 从位于目标文件夹下的构建 jar 执行...

    Java实现Web服务器和客户端

    在本实验中,我们将探讨如何使用Java来实现一个Web服务器和客户端。这涉及到Java的Socket编程,HTTP协议的理解,以及并发处理技术。首先,我们来深入理解这些关键知识点。 **Java Socket编程** Java Socket是Java...

    JAVA-NIO-DEMO

    在NIO的上下文中,注解可能被用于配置NIO相关的服务,如网络服务器的端口设置。 再来说说Applet,它是Java的一种小程序,可以在浏览器中运行。然而,由于安全性和现代Web技术的发展,Applet的使用已经逐渐减少。在...

    分布式Java中的TCP/IP+NIO

    在分布式Java应用中,NIO常用于构建高并发的服务端,例如Web服务器、消息中间件等。服务器通常使用Selector来监控多个通道的状态变化,一旦有新的连接请求或数据到达,Selector会唤醒处理线程,避免了为每个连接分配...

    基于Java的实例源码-开发的简单WEB服务器源码.zip

    这是一个关于使用Java编程语言开发简单WEB服务器的实例源码包。在Java中,我们可以利用其强大的网络编程功能来实现一个基础的HTTP服务器。这个压缩包可能包含了一个或多个Java源代码文件,这些文件用于处理HTTP请求...

    Peach:具有NIO的轻量级Web容器

    【Peach:具有NIO的轻量级Web容器】是一个基于Java开发的高效、轻量级的Web服务器和Web应用程序容器。它利用了Java的非阻塞I/O(New IO,即NIO)特性,提供了高并发处理能力,特别适合于处理大量短连接的场景,如API...

    JDK_7_NIO2

    ### JDK 7 NIO2 新特性...为了更好地理解异步套接字通道的使用,我们来看一个简单的客户端/服务器示例。 ##### 设置服务器 首先,我们需要创建一个 `AsynchronousServerSocketChannel` 并绑定到一个地址: ```java ...

    tcp.zip_java Tcp _java nio_java nio TCP_tcp_tcp java

    在“tcp.zip”压缩包内的文件,很可能是包含了一个使用Java NIO实现的TCP服务器示例,展示了如何创建和管理多个客户端连接。代码可能包含了以下关键部分: 1. 初始化ServerSocketChannel并绑定到指定端口。 2. 创建...

    aio_bio_nio.rar

    - **NIO**:常用于需要处理大量并发连接的服务器,如高并发的Web服务器、聊天服务器等。 - **AIO**:适合大型分布式系统,或者需要优化CPU资源利用率,且需要处理大量并发连接的场景。 了解并熟练掌握这三种I/O模型...

Global site tag (gtag.js) - Google Analytics