- Everything You Need To Know about TCP/IP but Failed to Learn in Kindergarten
- A Client Socket in Java
- Sending Email by Java
- A Server Socket in Java
- HTTP and Web Browsing: Retrieving HTTP Pages
- How to Make an Applet Write a File on the Server
- A Multithreaded HTTP Server
- A Mapped I/O HTTP Server
- Further Reading
- Exercises
- Some Light Relief—Using Java to Stuff an Online Poll
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.