Non Blocking I/O Example: New Way

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.Iterator;
import java.net.*;

public class SingleFileHTTPServerNewIO {

  private ByteBuffer contentBuffer;
  private int port = 80;

  public SingleFileHTTPServerNewIO(ByteBuffer data, String encoding, 
   String MIMEType, int port) throws UnsupportedEncodingException {
    
    this.port = port;
    String header = "HTTP/1.0 200 OK\r\n"
     + "Server: OneFile 1.0\r\n"
     + "Content-length: " + data.limit() + "\r\n"
     + "Content-type: " + MIMEType + "\r\n\r\n";
    byte[] headerData = header.getBytes("ASCII");

    this.contentBuffer = ByteBuffer.allocateDirect(data.limit() + headerData.length);
    contentBuffer.put(headerData);
    contentBuffer.put(data);
    
  }
  
  public void run() throws IOException {
  
    ServerSocketChannel serverChannel = ServerSocketChannel.open();
    ServerSocket  serverSocket = serverChannel.socket();
    Selector selector = Selector.open();
    InetSocketAddress localPort = new InetSocketAddress(port);
    serverSocket.bind(localPort);
    serverChannel.configureBlocking(false);
    serverChannel.register(selector, SelectionKey.OP_ACCEPT);

    while (true) {
      int n = selector.select();
      if (n == 0)  continue;

      Iterator keys = selector.selectedKeys().iterator();
      while (keys.hasNext()) {
        SelectionKey key = (SelectionKey) keys.next();
        if (key.isAcceptable()) {
          ServerSocketChannel server = (ServerSocketChannel) key.channel();
          SocketChannel channel = server.accept();
          registerChannel(selector, channel, SelectionKey.OP_READ);
          sendFile(channel); 
        }
        keys.remove();
      }
    }
  }

  private void registerChannel (Selector selector, SelectableChannel channel, int ops)
    throws IOException {
    if (channel == null) return;
    channel.configureBlocking(false);
    channel.register(selector, ops);
  }

  private ByteBuffer buffer = ByteBuffer.wrap(new byte[4096]);

  private String readHeader(SelectionKey key) throws IOException {

     SocketChannel channel = (SocketChannel) key.channel();
     int count;

     buffer.clear();
     
     // read the HTTP header
     StringBuffer request = new StringBuffer(80);
     while ((count = channel.read(buffer)) > 0) {
        buffer.flip();
        byte[] data = buffer.array();
        request.append(new String(data, 0, buffer.limit()-1, "ASCII"));    
        System.out.println(request);
        if (request.toString().endsWith("\n")) return request.toString();
        
        buffer.clear();
      }

      if (count < 0) channel.close();
      return request.toString();
      
  }

  private void sendFile (SocketChannel channel) throws IOException {
     contentBuffer.clear(); // this actually resets but does not clear data
     channel.write(contentBuffer);
     channel.close();
  }  

  public static void main(String[] args) {

    try {
      String contentType = "text/plain";
      if (args[0].endsWith(".html") || args[0].endsWith(".htm")) {
        contentType = "text/html";
      }
      
      FileInputStream fin = new FileInputStream(args[0]);
      FileChannel in = fin.getChannel();
      MappedByteBuffer input = in.map(FileChannel.MapMode.READ_ONLY, 0, in.size());
        
      // set the port to listen on
      int port;
      try {
        port = Integer.parseInt(args[1]);
        if (port < 1 || port > 65535) port = 80;
      }  
      catch (Exception e) {
        port = 80;
      }  
      
      String encoding = "ASCII";
      if (args.length > 2) encoding = args[2]; 
       
      SingleFileHTTPServerNewIO server = new SingleFileHTTPServerNewIO(input, encoding,
       contentType, port);
      server.run();         

    }
    catch (Exception ex) {
      ex.printStackTrace();
      System.err.println(ex);
    }
  
  }

}

Previous | Next | Top | Cafe au Lait |Cafe con Leche

Copyright 1999, 2002 Elliotte Rusty Harold
elharo@metalab.unc.edu
Last Modified November 1, 2002