Download
Download now! (v0.1 beta - 151KB)
Follow the file release RSS feed...
Description
The files UdpServer.java, TcpServer.java, and NioServer.java contain Public Domain classes to help embedding network servers in your code. They are thread-safe and robust and well-suited to either GUI or command line applications.
Why
Why provide server code when it's so easy (and fun!) for anyone to write their own in Java? I got tired of always rewriting little UDP and TCP servers for this project or that. Inevitably I'd start with the ol' 10-lines-or-less version, which works great in Java, but then I'd want to be able to change the listening port on the fly or join a multicast group, and I'd have to change my code because it wasn't robust enough in 10 lines. Finally I threw in the towel and wrote good ones to use over and over.
Usage
You can copy just the file you need into
your project in whatever package you're using.
If you want to try compiling the files on the command line
to play with the examples, go to the src
directory,
and type javac *.java
Here is an example of an Echo program that echoes UDP packets to the console as well as echoing the packets back to the sender:
public class UdpEchoExample { public static void main(String[] args) throws Exception{ int port = 1234; try{ port = Integer.parseInt(args[0]); } catch( Exception exc ){ System.out.println("No port, or bad port, provided. Will use " + port ); } // end catch UdpServer us = new UdpServer(); // Create the server us.setPort( port ); // Set the port us.addUdpServerListener( new UdpServer.Listener() { // Add listener @Override public void packetReceived( UdpServer.Event evt ) { // Packet received System.out.println( evt.getPacketAsString() ); // Write to console try { evt.send( evt.getPacket() ); // Packet magically already contains // return address information } catch( java.io.IOException ex ) { ex.printStackTrace(); // Please don't use printStackTrace in production code } // end ctach } // end packetReceived }); // end Listener us.start(); System.out.println("Server started on port " + port ); } // end main } // end class UdpEchoExample
Here is another Echo program, this time with TCP:
public class TcpEchoExample { public static void main(String[] args) throws Exception{ int port = 1234; try{ port = Integer.parseInt(args[0]); } catch( Exception exc ){ System.out.println("No port, or bad port, provided. Will use " + port ); } // end catch TcpServer ts = new TcpServer(); // Create the server ts.setPort( port ); // Set the port ts.addTcpServerListener( new TcpServer.Listener() { // Add listener @Override public void socketReceived( TcpServer.Event evt ) { // New stream try { InputStream in = evt.getSocket().getInputStream(); // Input OutputStream out = evt.getSocket().getOutputStream(); // Output byte[] buff = new byte[64]; // Buffer int num = -1; // Bytes read while( (num = in.read(buff)) >= 0 ){ // Not EOS yet System.out.print(new String(buff,0,num) ); // Echo to console out.write( buff, 0, num ); // Echo to source out.flush(); // Flush stream } // end while } catch( IOException exc ) { exc.printStackTrace(); } finally { try { evt.getSocket().close(); } catch( IOException exc2 ) { exc2.printStackTrace(); } } } // end socketReceived }); // end Listener ts.start(); System.out.println("Server started on port " + port ); } // end main } // end class TcpEchoExample
Finally if you're curious about the java.nio
package,
the so-called New IO (not so new anymore), you can use the NioServer class
such as in this echo example:
public class NioEchoExample { public static void main(String[] args) throws Exception{ if( args.length == 0 ){ System.out.println("\nNo ports provided. Using port 1234 as default."); args = new String[]{ "1234" }; } // Parse command line port requests NioServer ns = new NioServer(); // New server for( String s : args ){ try{ int port = Integer.parseInt(args[0]); SocketAddress addr = new InetSocketAddress(port); ns.addTcpBinding(addr).addUdpBinding(addr); // Bind to TCP and UDP System.out.println(" Listening on port " + port ); } catch( Exception exc ){ System.out.println("To specify a port, include it as the first argument."); } } // end for ns.addNioServerListener(new NioServer.Adapter() { // Listener Charset charset = Charset.forName( "US-ASCII" ); // Only print ASCII text /** * Echo all TCP data as it is received. */ @Override public void tcpDataReceived(NioServer.Event evt) { ByteBuffer inBuff = evt.getInputBuffer(); // Input buffer inBuff.mark(); // Remember where we started System.out.print( charset.decode( inBuff ) ); // Echo to console inBuff.reset(); // Back to the mark ByteBuffer outBuff = evt.getOutputBuffer(); // Output buffer outBuff.clear(); // Clear output outBuff.put( inBuff ); // Copy input into output outBuff.flip(); // Prepare output for playback } /** * Echo all UDP data as it is received. */ @Override public void udpDataReceived(NioServer.Event evt) { // Same as TCP method! ByteBuffer inBuff = evt.getInputBuffer(); // Input buffer inBuff.mark(); // Remember where we started System.out.print( charset.decode( inBuff ) ); // Echo to console inBuff.reset(); // Back to the mark ByteBuffer outBuff = evt.getOutputBuffer(); // Output buffer outBuff.clear(); // Clear output outBuff.put( inBuff ); // Copy input into output outBuff.flip(); // Prepare output for playback } }); ns.start(); } // end main } // end NioEchoExample
API
I've done my best to thoroughly document the code, if you care to look at the source, or simply view the javadoc-generated API.
Licensing
This code is released into the Public Domain. Enjoy.
Changes
- v0.1 - Initial release.
A Note About Public Domain
I have released this software into the Public Domain. That means you can do whatever you want with it. Really. You don't have to match it up with any other open source license &em; just use it. You can rename the files, move the Java packages, whatever you want. If your lawyers say you have to have a license, contact me, and I'll make a special release to you under whatever reasonable license you desire: MIT, BSD, GPL, whatever.
blog comments powered by Disqus