Home > Articles > Programming > Java

  • Print
  • + Share This
This chapter is from the book

This chapter is from the book

A Mapped I/O HTTP Server

The final section of this chapter presents the code to use the new mapped I/O facility in a socket server. Sun distributes a sample mapped I/O socket application with JDK 1.4 beta. However, their sample application does not work on Windows 98. It hangs in the accept() statement.

I reported the bug to Sun and hope it will be fixed in the final release. It may not be: after all, mapped I/O is a server feature, and Windows 9x is not a server operating system. Anyway, as a refresher, an example of channel I/O on files would be this program that duplicates a file:

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.net.*;
class Files {

  void copyThruChannel(String fname) throws Exception {
    File f = new File(fname);
    FileInputStream fin = new FileInputStream(f);
    int len = (int) f.length();

    FileChannel fc = fin.getChannel();
    System.out.println("allocating buff");
    ByteBuffer myBB = ByteBuffer.allocate(len);
    int bytesRead = fc.read(myBB);
    myBB.flip();

    System.out.println("getting fout channel");
    FileOutputStream fos = new FileOutputStream(fname+".copy.txt");
    FileChannel fco = fos.getChannel();
    int bytesWritten = fco.write(myBB);
    fco.close();
  }

  public static void main(String a[]) throws Exception {

    Files client = new Files();
    client.copyThruChannel(a[0]);
  }
}

In a similar way, the code to update our HTTP server, so that it uses channel I/O, looks like this:

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.net.*;
class OneConnection_D extends OneConnection_C {

  OneConnection_D(Socket sock) throws Exception {
    super(sock);
  }  

  void sendThruChannel(String fname) throws Exception {
    File f = new File(fname);
    FileInputStream fin = new FileInputStream(f);
    int len = (int) f.length();

    FileChannel fc = fin.getChannel();
    System.out.println("allocating buff");
    ByteBuffer myBB = ByteBuffer.allocate(len);
    int bytesRead = fc.read(myBB);
    myBB.flip();

    System.out.println("getting sock channel");
    SocketChannel sc = sock.getChannel();
    int bytesWritten = sc.write(myBB);
    sc.close();
  }
}

public class HTTPServer4 {
  public static void main(String a[]) throws Exception {

    final int httpd = 80;
    ServerSocketChannel ssc = ServerSocketChannel.open();
    InetSocketAddress isa
    = new InetSocketAddress(InetAddress.getLocalHost(), httpd);
	ssc.socket().bind(isa);
    System.out.println("have opened port 80 locally!");

    System.out.println("waiting for accept");
    Socket sock = ssc.accept();
    System.out.println("client has made socket connection");

    OneConnection_D client = new OneConnection_D(sock);
    String filename = client.getRequest();
    client.sendThruChannel(filename);
  }
}

Note: This version is not multithreaded to keep the code focused on the issue of interest. The main routine shows how you have to open a server socket channel, then bind it to the port of interest. From here it is easy to use mapped I/O.

  • + Share This
  • 🔖 Save To Your Account