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.