SocketConnection

SocketConnection

Released 4 years ago , Last update 8 months ago

Open Source Code for a Java Socket connection.

Manages a Java Socket connection. Written originally for a network game where both client and server programs were massively multi-threaded. Given an active Socket, the program keeps writes from multiple threads organized and makes incoming data available on a dedicated thread. Thoroughly Javadoc'ed.

Code deals with the threads needed to use a socket as well as the threads that may want to write to the socket simultaneously. Provides a thread to read from the socket. Gracefully handles the many problems and failures than can beset socket connections. Useful as is and can serve as a good example of programming with sockets.

A test program is provided that establishes a connection and feeds data both ways.

Pricing

FREE

Personal License

  • Perpetual license

  • 1 site, 1 server

  • No distribution (hosted use only)

  • Non-commercial use

  • Attribution required

Usage Example

The following is a simplified version of the sample usage code included with the source code:

package rrc12;

import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;

import rrc12.util.*;
import rrc12.util.socketconnection.*;

/** An example of using SocketConnection.
 * This class is a blank window.  While
 * socket operations have nothing necessarily to do with windows, this
 * class can produce an array of error messages, most of which must come
 * to the attention of the user/developer immediately, and the best way
 * to do that is with message boxes.  Hence a window to serve as a parent
 * to those message boxes.
 * 

Starts listening at port 6212 and echoes back everything * sent to the port. * Then fires up a client thread to send info to the port. * Sends arbitrary data to the server and writes it to the Standard Output * when the server returns it.

*/ public class Sample extends JFrame { // *** Class Fields *** private static final int PORT = 6212; private static Sample mainWindow; // *** Class Methods *** /** The main program. */ public static void main( String[] args ) { mainWindow = new Sample(); mainWindow.setVisible( true ); // Start up the client. mainWindow.runClient(); } // *** Instance Fields *** private ServerSocket serverSocket = null; /** A ProcessData implementation to handle both ends of a socket. * As they both, necessarily, use the same format, the read and write * methods can be the same. */ private abstract class AbstractProcessData implements ProcessData { public Object read( DataInput in ) throws IOException { for (;;) { int type = in.readByte(); switch (type) { case 2: return in.readUTF(); case 3: int i = in.readInt(); return new Integer( i ); case 4: long lng = in.readLong(); return new Long( lng ); } } } public void write( Object o, DataOutput out ) throws IOException { if (o instanceof String) { out.writeByte( 2 ); out.writeUTF( (String) o ); } else if (o instanceof Integer) { out.writeByte( 3 ); out.writeInt( ((Integer) o).intValue() ); } else if (o instanceof Long) { out.writeByte( 4 ); out.writeLong( ((Long) o).longValue() ); } } } /** A ProcessData implementation to handle the server end of a socket. * In this case, it echoes back whatever comes in from the client. * (Note that once a socket is established, which end is the client * and which end is the server is somewhat arbitrary and even * meaningless.) */ private class ServerConnect extends AbstractProcessData { private volatile SocketConnection sConnect; private ServerConnect( SocketConnection sc ) { sConnect = sc; } public void respond( Object o ) { SocketConnection conn = sConnect; if (conn == null) return; if (o instanceof Integer && ((Integer) o).intValue() == 99) { conn.willShutDown(); System.out.println( "Normal end. Close main window whenever."); } conn.getSocketOutput().write( o ); // Echo back to client. } public void terminate( Exception e ) { Utilities.terminateProgram( Sample.this, e, "Server ProcessData" ); } } /** A ProcessData implementation to handle the server end of a socket. * In this case, it writes everything sent from the server to the * Standard Output. */ private class ClientConnect extends AbstractProcessData { private volatile SocketConnection sConnect; private ClientConnect( SocketConnection sc ) { sConnect = sc; } public void respond( Object o ) { if (o instanceof Integer && ((Integer) o).intValue() == 99) { SocketConnection conn = sConnect; if (conn == null) return; if (!conn.isActive()) return; conn.willShutDown(); conn.setSocket( null, true ); conn.dispose(); System.out.println( "Client has shut down."); // Program is now done. Could call System.exit( 0 ) here. return; } System.out.println( o.toString() ); } public void terminate( Exception e ) { Utilities.terminateProgram( Sample.this, e, "Client ProcessData" ); } } // *** Instance Methods *** /** Creates a new SocketSample. */ private Sample() { setBounds( 100, 100, 150, 100 ); setDefaultCloseOperation( DISPOSE_ON_CLOSE ); addWindowListener( new WindowAdapter() { public void windowClosed( WindowEvent e ) { System.exit( 0 ); } } ); // Create a ServerSocket to be used by portListening method. try { serverSocket = new ServerSocket( PORT, 50, null ); } catch (Exception e) { // Warn user of major runtime exception. quitPort(); return; } Thread t = new Thread() { public void run() { portListening(); } }; t.start(); try { Thread.sleep( 2000 ); } catch (InterruptedException ie) {} } /** Establishes and starts running a client connection. */ private void runClient() { // Set up SocketConnection. SocketConnection client = new SocketConnection(); SocketOutput sout = client.getSocketOutput(); client.setMessageWindow( this ); client.setName( "Test Client" ); client.addListener( new SocketConnection.Listener() { public void unexpectedDisconnect( SocketConnection sc ) { System.out.println( "Client disconnected unexpectedly."); } } ); // The data handler handles all reads on the socket and, in this // case, finally takes control of the client and shuts it down. client.setDataHandler( new ClientConnect( client ) ); // Get a Socket. Socket socket; try { socket = new Socket( "127.0.0.1", PORT ); } catch (Exception e) { // Warn user of major runtime exception. socket = null; } if (socket != null) { // Demonstrate that we can write to SocketOutput before // it has been given a connection. sout.write( "First Line" ); // Apply the socket to the existing socket connection. client.setSocket( socket, true ); // Write to the connected socket. sout.write( "Second Line" ); sout.write( new Integer( 99 )); } } /** Listens at a port (server connection). */ private void portListening() { for (;;) { if (serverSocket == null) break; // Wait for a connection. Socket s; try { s = serverSocket.accept(); } catch (Exception e) { if (serverSocket == null) break; continue; } if (serverSocket == null) break; if (s == null) continue; // Made a good connection. // Put a new SocketConnection in place. final SocketConnection connection = new SocketConnection(); connection.setMessageWindow( this ); connection.setName( "Test Server" ); connection.addListener( new SocketConnection.Listener() { public void unexpectedDisconnect( SocketConnection sc ) { System.out.println( "Client has finished abnormally." ); connection.willShutDown(); connection.setSocket( null, true ); connection.dispose(); quitPort(); } } ); ProcessData connect = new ServerConnect( connection ); connection.setDataHandler( connect ); connection.setSocket( s, true ); } // End serverLoop quitPort(); } /** Disconnects the server socket from the port and stops * listening for possible connections. */ private void quitPort() { if (serverSocket != null) { try { serverSocket.close(); } catch (IOException e) {} serverSocket = null; } } }
2 licenses, starting from From » FREE View Licenses

Get A Quote

What do you need?
  • Custom development
  • Integration
  • Customization / Reskinning
  • Consultation
When do you need it?
  • Soon
  • Next week
  • Next month
  • Anytime

Thanks for getting in touch!

Your quote details have been received and we'll get back to you soon.


Or enter your name and Email
No comments have been posted yet.