public class SocketProtocol
extends java.lang.Object
The class implements both the "local" controller side and the "remote" ServerSocket side in order to keep the protocol implementation for both sides correct.
This class is not normally used directly, but thru subclasses of AbstractProtocolRunner
which provides the necessary separate Threading required for the SocketProtocol.
Currently, this protocol expects remote TCP services to be running and accepting connections
on port DEFAULT_REMOTE_PORT
at the first, if port DEFAULT_REMOTE_PORT
is no available,
remote TCP services will try to run on 2412, 2414 ... with augmentation of pace 2, the maximum possible
port is MAX_SERVER_PORT
.
By trying a broad range of ports, it can prevent conflicts with other system resources.
Currently, this protocol lets local controller to contact and attempt a connection to
those remote TCP services. As those TCP services can choose port dynamically, the local controller
doesn't know which remote port to use for the connection. It will try to connect to port DEFAULT_REMOTE_PORT
,
if fail it will try to connect to port 2412, 2414 ... with augmentation of pace 2, the maximum possible
port is MAX_SERVER_PORT
.
If there is no need for the local controller's port to be specific--such as using port forwarding to local emulators appearing as remote machines--then the local controller port really could be any port at all.
There is an initial handshake or verification that occurs between the local and remote SocketProtocol instances to confirm the device port owners are both SocketProtocol implementations.
Modifier and Type | Field and Description |
---|---|
boolean |
_debugEnabled
set to false to disable debug logging and improve performance.
|
protected int |
controllerPort
port to use for a local controller Runner.
|
protected java.net.Socket |
controllerRunner
local controller Socket connection.
|
protected static java.lang.String |
debugprefix |
static int |
DEFAULT_CONTROLLER_PORT |
static int |
DEFAULT_REMOTE_PORT |
static java.lang.String |
DEFAULT_SERVER |
static java.lang.String |
ENV_KEY_REMOTE_PORT |
protected java.lang.String |
EOM
"[!_!]"
Case-Insensitive End-Of-Message marker for all character messages exchanged between local and remote runners.
Normally, this is never changed. |
static int |
MAX_SERVER_PORT |
static java.lang.String |
MSG_PROTOCOL_VERSION_QUERY
"PROTOCOLVERSION"
Prompt and partial response for initial handshake between the local protocol runner and a remote
protocol runner.
|
static int |
NEXT_SERVER_PORT_PACE |
protected java.lang.String |
remoteHostname
Hostname to contact for a remote client Runner.
|
protected int |
remotePort
port to contact for a remote client Runner.
|
static int |
STATUS_SHUTDOWN_CONTROLLER
Indicates the Socket is being shutdown because from the controller side.
|
static int |
STATUS_SHUTDOWN_NORMAL
Indicates the Socket is being shutdown normally.
|
static int |
STATUS_SHUTDOWN_REMOTE_CLIENT
Indicates the Socket is being shutdown abnormally no
remote client connection will be possible.
|
static int |
STATUS_SHUTDOWN_REMOTE_SERVICE
Indicates the Socket is being shutdown abnormally because no
remote service connection will be possible.
|
protected static java.lang.String[] |
STATUS_STRINGS
String representations of the STATUS_SHUTDOWN causes.
|
java.lang.String |
TAG |
Constructor and Description |
---|
SocketProtocol()
Default no-op constructor using all defaults.
|
SocketProtocol(NamedListener listener)
Constructor using all defaults while registering a NamedListener.
|
SocketProtocol(NamedListener listener,
boolean local_mode)
Constructor using all defaults while registering a NamedListener and
setting the local or remote mode of the instance.
|
Modifier and Type | Method and Description |
---|---|
boolean |
acceptProtocolVersion(int protocol)
By default, this class only accepts connections from instances using the same
protocol version.
|
boolean |
addListener(NamedListener listener)
Register a DebugListener/ConnectionListener.
|
protected void |
bindToRemoteServer()
Create the Socket object according to server name and port.
|
void |
closeProtocolRunners()
Simply callse closeStreams
|
boolean |
connectProtocolRunners()
Attempt to create appropriate local or remote socket connections and attempt to
connect with the other side.
|
protected void |
debug(java.lang.String text)
Convenience routine for logging debug messages.
|
int |
getClientConnectTimeout()
Default is set at 60 seconds.
|
int |
getConnectedProtocol() |
int |
getControllerPort()
The default port currently used for outgoing controller Socket connections is 2411.
|
java.lang.String |
getEOM() |
boolean |
getKeepAlive()
By default keepAlive is TRUE unless changed.
|
int |
getNextPort(int prevPort)
Try to augment the port number by 2
|
java.lang.String |
getRemoteHostname()
The default remote hostname is/was typically the "localhost".
|
int |
getRemotePort()
The default port currently used for remote client connections--typically port 2410.
|
static java.lang.String |
getShutdownCauseDescription(int cause) |
boolean |
isConnected() |
boolean |
isLocalMode() |
boolean |
removeListener(NamedListener listener) |
boolean |
sendResponse(java.lang.String message)
Send UTF-8 encoded message to the connected instance, if any.
|
void |
setClientConnectTimeout(int clientConnectTimeout)
Default is set at 60 seconds.
|
void |
setControllerPort(int port)
Provide an alternate port on which the local controller should open a Socket.
|
void |
setEOM(java.lang.String marker) |
void |
setKeepAlive(boolean keepAlive)
By default keepAlive is TRUE unless changed.
|
void |
setLocalMode(boolean local_mode)
Set the mode of this instance.
|
void |
setRemoteHostname(java.lang.String hostname)
The default remote hostname is/was typically the "localhost".
|
void |
setRemotePort(int port)
Provide an alternate port on which the remote client is accepting connections.
|
java.lang.String |
waitForInput(long msTimeout)
Listen for UTF-8 encoded content from the connected instance and return it to the caller if
it is deemed valid.
|
public java.lang.String TAG
public static final java.lang.String DEFAULT_SERVER
public static final int DEFAULT_REMOTE_PORT
public static final int DEFAULT_CONTROLLER_PORT
public static final int MAX_SERVER_PORT
public static final int NEXT_SERVER_PORT_PACE
public static final java.lang.String MSG_PROTOCOL_VERSION_QUERY
public static final java.lang.String ENV_KEY_REMOTE_PORT
public static final int STATUS_SHUTDOWN_NORMAL
#shutdownThread
,
shutdownCause
,
Constant Field Valuespublic static final int STATUS_SHUTDOWN_REMOTE_CLIENT
#shutdownThread
,
shutdownCause
,
Constant Field Valuespublic static final int STATUS_SHUTDOWN_REMOTE_SERVICE
#shutdownThread
,
shutdownCause
,
Constant Field Valuespublic static final int STATUS_SHUTDOWN_CONTROLLER
#shutdownThread
,
shutdownCause
,
Constant Field Valuesprotected static final java.lang.String[] STATUS_STRINGS
protected java.lang.String EOM
protected java.lang.String remoteHostname
protected int remotePort
protected int controllerPort
protected java.net.Socket controllerRunner
public boolean _debugEnabled
protected static final java.lang.String debugprefix
public SocketProtocol()
public SocketProtocol(NamedListener listener)
listener
- NamedListener (DebugListener, ConnectionListener, etc...) to register with
the new instance. Ideally, the listener should implement both DebugListener and
ConnectionListener interfaces.public SocketProtocol(NamedListener listener, boolean local_mode)
By default, the class is setup to run in local controller mode. Users would normally only call this constructor to make local_mode = false and run in remote client mode.
The user should change any desired remote hostname/port settings prior to starting the full use of the instance.
listener
- NamedListener to register with the new instance. Ideally, the
listener should implement both DebugListener and ConnectionListener interfaces.public void setLocalMode(boolean local_mode) throws java.lang.IllegalThreadStateException
local_mode
- true to run in local protocol controller mode (ex: port 2411). false
to run in remote protocal client mode (ex: port 2410).java.lang.IllegalThreadStateException
- if a call attempts to set/change this while the
instance is already connected or running.public boolean isLocalMode()
public boolean addListener(NamedListener listener)
listener
- to register to receive notifications.notifyConnection()
,
notifyLocalShutdown(int)
,
notifyRemoteShutdown(int)
public boolean removeListener(NamedListener listener)
listener
- protected void debug(java.lang.String text)
text
- notifyDebug(String)
public static java.lang.String getShutdownCauseDescription(int cause)
cause
- -- int STATUS_SHUTDOWN_xxx cause to describe.STATUS_STRINGS
public java.lang.String getEOM()
public void setEOM(java.lang.String marker) throws java.lang.IllegalArgumentException
Case-insensitive
- End-Of-Message marker String to use for terminating all String messages in the protocol.
Normally, this is never changed. The local and remote runner implementations--coded
together (or this same class)--share in an implied contract of what this marker shall be
since both ends of the protocol must use it.java.lang.IllegalArgumentException
- if the supplied marker argument is null, zero-length, or appears to be
case-sensitive when comparing calls for toUpperCase() and toLowerCase().protected void bindToRemoteServer() throws java.io.IOException
java.io.IOException
public int getNextPort(int prevPort)
prevPort
- int, the previous port numberIllegalStateException,
- if the next port number exceeds the max port number.public boolean isConnected()
public boolean acceptProtocolVersion(int protocol)
protocol
- public void closeProtocolRunners()
closeStreams()
public java.lang.String waitForInput(long msTimeout) throws java.io.InvalidObjectException
String content is not considered valid unless/until the End-Of-Message marker is received. Without receiving the EOM within the timeout period the routine will consider any received content invalid and will subsequently return a null value upon timeout.
msTimeout
- timeout in millisecondsjava.io.InvalidObjectException
- if we have no InputStream connected.EOM
public boolean sendResponse(java.lang.String message) throws java.io.InvalidObjectException
message
- java.io.InvalidObjectException
- if we have no OutputStream connected.EOM
public boolean connectProtocolRunners()
isConnected()
,
createRemoteServerSocket()
,
acceptControllerConnection(int)
,
createRemoteClientConnection(int)
public boolean getKeepAlive()
public void setKeepAlive(boolean keepAlive)
keepAlive
- the keepAlive to setpublic java.lang.String getRemoteHostname()
public void setRemoteHostname(java.lang.String hostname)
the
- server hostname on which we expect remote clients to accept connections.public int getRemotePort()
public void setRemotePort(int port)
remote
- server port on which the remote client is accepting connections.public int getControllerPort()
Typically Sockets can normally communicate on "any available port". However the initial use and implementation for this protocol was for talking with simulators and emulators acting as remote devices on the local machine. Thus, it was necessary to be able to do port forwarding to specifically forward a known local controller port to the known remote client port.
public void setControllerPort(int port)
the
- port on which the local controller Socket will attempt to communicate.public int getConnectedProtocol() throws java.io.InvalidObjectException
java.io.InvalidObjectException
- if we have not successfully connected to a remote client.public int getClientConnectTimeout()
createRemoteClientConnection(int)
public void setClientConnectTimeout(int clientConnectTimeout)
createRemoteClientConnection(int)
clientConnectTimeout
- in secondsCopyright © SAS Institute. All Rights Reserved.