com.realtime.crossfire.jxclient.server.socket
Class ClientSocket

java.lang.Object
  extended by com.realtime.crossfire.jxclient.server.socket.ClientSocket

public class ClientSocket
extends java.lang.Object

A socket that processes incoming data.

 final ClientSocket clientSocket = new ClientSocket(...);
 clientSocket.writePacket(...);
 clientSocket.disconnect();


Field Summary
private  java.util.Collection<ClientSocketListener> clientSocketListeners
          The ClientSocketListeners to notify.
private  DebugWriter debugProtocol
          The appender to write state changes to.
private  boolean disconnectPending
          If set, notify listeners.
private  java.lang.String host
          The host to connect to.
private  byte[] inputBuf
          The receive buffer.
private  java.nio.ByteBuffer inputBuffer
          The receive buffer.
private  int inputLen
          If set to -1, a two-byte packet header is read next from inputBuffer.
private  int interestOps
          The currently set interest ops for selectionKey.
private  boolean isConnected
          Whether socketChannel is connected.
private static int MAXIMUM_PACKET_SIZE
          The maximum payload size of a Crossfire protocol packet.
private  java.nio.ByteBuffer outputBuffer
          The output buffer.
private  byte[] packetHeader
          A buffer for sending packets.
private  int port
          The port to connect to.
private  boolean reconnect
          Set if host or port has changed and thus a reconnect is needed.
private  boolean reconnectIsError
          Only valid if reconnect is set.
private  java.lang.String reconnectReason
          Only valid if reconnect is set.
private  java.nio.channels.SelectableChannel selectableChannel
          The SelectableChannel of socketChannel.
private  java.nio.channels.SelectionKey selectionKey
          The SelectionKey registered to selectableChannel.
private  java.nio.channels.Selector selector
          The Selector used for waiting.
private  java.nio.channels.SocketChannel socketChannel
          The SocketChannel when connected.
private  java.lang.Object syncConnect
          Synchronization object for reconnect, host, port, and disconnectPending.
private  java.lang.Object syncOutput
          Synchronization object for outputBuffer, selectionKey, interestOps, and socketChannel.
private  java.lang.Thread thread
          The Thread used to operate the socket.
 
Constructor Summary
ClientSocket(DebugWriter debugProtocol)
          Creates a new instance.
 
Method Summary
 void addClientSocketListener(ClientSocketListener clientSocketListener)
          Adds a ClientSocketListener to be notified.
 void connect(java.lang.String host, int port)
          Connects to a server.
 void disconnect(java.lang.String reason, boolean isError)
          Terminates the connection.
private  void doConnect()
          Processes pending connect requests.
private  void doReconnect()
          Processes pending re- or disconnect requests.
private  void doTransceive()
          Processes pending data to receive of transmit.
private  void process()
          Reads/writes data from/to the socket.
private  void processConnect(java.lang.String host, int port)
          Connects the socket.
private  void processDisconnect(java.lang.String reason, boolean isError)
          Disconnects the socket.
private  void processRead()
          Reads data from the socket and parses the data into commands.
private  void processReadCommand()
          Parses data from inputBuffer into commands.
private  void processWrite()
          Writes some pending data to the socket.
 void removeClientSocketListener(ClientSocketListener clientSocketListener)
          Removes a ClientSocketListener to be notified.
 void start()
          Starts operation.
 void stop()
          Stops operation.
private  void updateInterestOps()
          Updates selectionKey's interest ops to match interestOps.
private  void updateWriteInterestOps()
          Updates interestOps's OP_WRITE according to whether outputBuffer has pending data.
 void writePacket(byte[] buf, int len)
          Writes a packet.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

clientSocketListeners

@NotNull
private final java.util.Collection<ClientSocketListener> clientSocketListeners
The ClientSocketListeners to notify.


debugProtocol

@Nullable
private final DebugWriter debugProtocol
The appender to write state changes to. May be null to not write anything.


disconnectPending

private boolean disconnectPending
If set, notify listeners.


host

@Nullable
private java.lang.String host
The host to connect to. Set to null for disconnect.


inputBuf

@NotNull
private final byte[] inputBuf
The receive buffer. It is wrapped into inputBuffer.


inputBuffer

@NotNull
private final java.nio.ByteBuffer inputBuffer
The receive buffer. Contains data pending to be processed.


inputLen

private int inputLen
If set to -1, a two-byte packet header is read next from inputBuffer. Otherwise it is set to the packet length which will be read from inputBuffer.


interestOps

private int interestOps
The currently set interest ops for selectionKey.


isConnected

private boolean isConnected
Whether socketChannel is connected.


MAXIMUM_PACKET_SIZE

private static final int MAXIMUM_PACKET_SIZE
The maximum payload size of a Crossfire protocol packet.

See Also:
Constant Field Values

outputBuffer

@NotNull
private final java.nio.ByteBuffer outputBuffer
The output buffer. Contains data pending to send.


packetHeader

@NotNull
private final byte[] packetHeader
A buffer for sending packets.


port

private int port
The port to connect to.


reconnect

private boolean reconnect
Set if host or port has changed and thus a reconnect is needed.


reconnectIsError

private boolean reconnectIsError
Only valid if reconnect is set.


reconnectReason

@NotNull
private java.lang.String reconnectReason
Only valid if reconnect is set.


selectableChannel

@Nullable
private java.nio.channels.SelectableChannel selectableChannel
The SelectableChannel of socketChannel.


selectionKey

@Nullable
private java.nio.channels.SelectionKey selectionKey
The SelectionKey registered to selectableChannel. It's interesting ops are interestOps.


selector

@NotNull
private final java.nio.channels.Selector selector
The Selector used for waiting.


socketChannel

@Nullable
private java.nio.channels.SocketChannel socketChannel
The SocketChannel when connected. Set to null when not connected.


syncConnect

@NotNull
private final java.lang.Object syncConnect
Synchronization object for reconnect, host, port, and disconnectPending.


syncOutput

@NotNull
private final java.lang.Object syncOutput
Synchronization object for outputBuffer, selectionKey, interestOps, and socketChannel.


thread

@NotNull
private final java.lang.Thread thread
The Thread used to operate the socket.

Constructor Detail

ClientSocket

public ClientSocket(@Nullable
                    DebugWriter debugProtocol)
             throws java.io.IOException
Creates a new instance.

Parameters:
debugProtocol - tf non-null, write all protocol commands to this writer
Throws:
java.io.IOException - if the socket cannot be created
Method Detail

addClientSocketListener

public void addClientSocketListener(@NotNull
                                    ClientSocketListener clientSocketListener)
Adds a ClientSocketListener to be notified.

Parameters:
clientSocketListener - the client socket listener to add

connect

public void connect(@NotNull
                    java.lang.String host,
                    int port)
Connects to a server. Disconnects an existing connection if necessary.

Parameters:
host - the host to connect to
port - the port to connect to

disconnect

public void disconnect(@NotNull
                       java.lang.String reason,
                       boolean isError)
Terminates the connection. Does nothing if not connected.

Parameters:
reason - the reason for the disconnect
isError - whether the disconnect is unexpected

doConnect

private void doConnect()
                throws java.io.IOException
Processes pending connect requests.

Throws:
java.io.IOException - if an I/O error occurs

doReconnect

private void doReconnect()
                  throws java.io.IOException
Processes pending re- or disconnect requests.

Throws:
java.io.IOException - if an I/O error occurs

doTransceive

private void doTransceive()
                   throws java.io.IOException
Processes pending data to receive of transmit.

Throws:
java.io.IOException - if an I/O error occurs

process

private void process()
Reads/writes data from/to the socket. Returns if the thread has been interrupted.


processConnect

private void processConnect(@NotNull
                            java.lang.String host,
                            int port)
                     throws java.io.IOException
Connects the socket. The socket must not be connected.

Parameters:
host - the host to connect to
port - the port to connect to
Throws:
java.io.IOException - if an I/O error occurs

processDisconnect

private void processDisconnect(@NotNull
                               java.lang.String reason,
                               boolean isError)
Disconnects the socket. Does nothing if not currently connected.

Parameters:
reason - the reason for disconnection
isError - whether the disconnect is unexpected

processRead

private void processRead()
                  throws java.io.IOException
Reads data from the socket and parses the data into commands.

Throws:
java.io.IOException - if an I/O error occurs

processReadCommand

private void processReadCommand()
Parses data from inputBuffer into commands.


processWrite

private void processWrite()
                   throws java.io.IOException
Writes some pending data to the socket. Does nothing if no pending data exists or if the socket does not accept data.

Throws:
java.io.IOException - if an I/O error occurs

removeClientSocketListener

public void removeClientSocketListener(@NotNull
                                       ClientSocketListener clientSocketListener)
Removes a ClientSocketListener to be notified.

Parameters:
clientSocketListener - the client socket listener to remove

start

public void start()
Starts operation.


stop

public void stop()
          throws java.lang.InterruptedException
Stops operation.

Throws:
java.lang.InterruptedException - if stopping was interrupted

updateInterestOps

private void updateInterestOps()
Updates selectionKey's interest ops to match interestOps. Does nothing if selectionKey is null.


updateWriteInterestOps

private void updateWriteInterestOps()
Updates interestOps's OP_WRITE according to whether outputBuffer has pending data.


writePacket

public void writePacket(@NotNull
                        byte[] buf,
                        int len)
Writes a packet. The packet contents must not change until this function has returned.

This function may be called even if the socket has been closed. In this case he packet is discarded.

Parameters:
buf - the packet to send
len - the number of bytes to send