📄 tcpconn.java
字号:
package org.trinet.waveserver.rt;
import java.io.*;
import java.net.*;
import java.util.*;
/** Implementation of a TRINET WaveClient connection class.
* This class is used to open a TCP socket connection to a specified host and port.
* Once connected, the TCPConn instance methods can be used to send/receive TCPMessage
* objects between a WaveClient and server instance via socket input/outstreams.
* A TCPMessage is comprised of a collection of DataField objects whose values are
* "serialized" into Packet objects which are then "serialized" as a byte stream by
* the TCPConn socket connection. The serialization is not java.io.Serializable,
* but rather a protocol implemented by subclasses of TrinetSerial which is
* defined in the WaveClinet/Server API documentation.
* @see TCPConnClient
* @see TrinetSerial
* @see TCPMessage
* @see Packet
*/
public class TCPConn {
/** Default socket read timeout value.*/
public static final int DEFAULT_TIMEOUT_MILLISECS = 5000;
public static final int DEFAULT_RECEIVE_SIZE = 16384;
/** End of file upon socket reading input. */
public static final int EOF = -1;
/** Socket receive stream */
protected BufferedInputStream socketInStream;
/** Socket send stream */
protected BufferedOutputStream socketOutStream;
/** Socket connected to server */
protected Socket socket;
/** Socket input timeout value. */
protected int timeoutDefault = DEFAULT_TIMEOUT_MILLISECS;
/** Buffer for a TRINET serialized DataField object. */
byte [] dataFieldBuffer = new byte [DataFieldConstants.DF_MAX_SERIAL_BYTES];
/** Default Constructor, no-op, null data members. */
public TCPConn() {}
/** Constructor creates new connection to specified host and port, configures socket, and opens i/o streams.
* @exception java.io.IOException error occurred during the socket connection and intialization.
* @exception java.lang.Security if SecurityManager exists and the checkConnect(...) doesn't allow connection.
*/
public TCPConn(String host, int port) throws IOException, UnknownHostException {
socket = new Socket(host, port);
initSocket();
}
/** Constructor creates new connection to specified host and port, configures socket, and opens i/o streams.
* @exception java.io.IOException error occurred during the socket connection and intialization.
* @exception java.lang.Security if SecurityManager exists its checkConnect(...) doesn't allow connection.
*/
public TCPConn(InetAddress inetAddr, int port) throws IOException {
socket = new Socket(inetAddr, port);
initSocket();
}
/** Constructor creates new connection to specified host and port, configures socket, and opens i/o streams.
* @exception java.io.IOException error occurred during the socket connection and intialization.
* @exception java.lang.NullPointerException input socket reference is null.
* @exception java.lang.Security if SecurityManager exists and the checkConnect(...) doesn't allow connection.
*/
public TCPConn(Socket socket) throws IOException {
if (socket == null) throw new NullPointerException("TCPConn null socket reference.");
this.socket = socket;
initSocket();
}
/** Creates new connection to specified host and port, configures socket, and opens i/o streams.
* @exception java.io.IOException error occurred during the socket connection and intialization.
* @exception java.lang.Security if SecurityManager exists its checkConnect(...) doesn't allow connection.
* @see #initSocket()
*/
public void createSocket(String host, int port) throws IOException, UnknownHostException {
if (socket != null) close();
socket = new Socket(host, port);
initSocket();
}
/** Closes the existing socket connection, if any, sets this object's socket reference to the input object.
* Configures the socket parameters, and opens new i/o streams.
* @exception java.io.IOException error occurred during intialization.
* @see #createSocket(String, int)
* @see #initSocket()
*/
void setSocket(Socket socket) throws IOException {
if (socket != null) close();
this.socket = socket;
initSocket();
}
/** Closes open socket if any, and attempts to re-establish connection to same host and port number.
* Does a no-op if socket is null.
* @exception java.io.IOException error occurred during the socket reconnection and intialization.
* @exception java.lang.Security if SecurityManager exists its checkConnect(...) doesn't allow connection.
* @see #createSocket(String, int)
* @see #initSocket()
*/
public void reset() throws IOException {
if (socket == null) return;
close();
socket = new Socket(socket.getInetAddress(), socket.getPort());
initSocket();
}
/** Sets socket attributes (e.g. input timeout), opens socket i/o streams.
* Does a no-op if socket is null.
* @exception java.io.IOException error occurred creating the i/o streams.
* @exception java.net.SocketException error occurred setting the socket property attributes.
* @see #createSocket(String, int)
* @see #reset()
*/
public void initSocket() throws IOException {
socket.setReceiveBufferSize(DEFAULT_RECEIVE_SIZE);
// socket.setSendBufferSize(DEFAULT_SEND_SIZE);
// socket.setTcpNoDelay(false);
// socket.setSoLinger(false, 1);
// socket.setKeepAlive(); // java 1.3 feature
if (socket == null) return;
socket.setSoTimeout(timeoutDefault);
socketInStream = new BufferedInputStream(socket.getInputStream());
socketOutStream = new BufferedOutputStream(socket.getOutputStream());
// System.out.println(getSocketInfo());
}
/** Closes socket i/o streams.
* @see #createSocket(String, int)
* @see #initSocket()
* @see #reset()
*/
public void close() {
try {
socketInStream.close();
socketOutStream.close();
socket.close();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
/** Sets the default timeout millisecs value to use for socket input. Returns true if successful.
*/
public boolean setDefaultTimeout(int timeoutMilliSecs) {
boolean retVal = true;
timeoutDefault = timeoutMilliSecs;
try {
socket.setSoTimeout(timeoutDefault);
}
catch (SocketException ex) {
ex.printStackTrace();
retVal = false;
}
return retVal;
}
/** Returns the remote (server) port number of the socket. */
public int getPort() {
return socket.getPort();
}
/** Returns the local (client) port number of the socket. */
public int getLocalPort() {
return socket.getLocalPort();
}
/** Returns the client address. */
public InetAddress getLocalAddress() {
return socket.getLocalAddress();
}
/** Returns the server address. */
public InetAddress getInetAddress() {
return socket.getInetAddress();
}
/** Returns true only if input object is an instance of this class and
* its local and remote host addresses and its corresponding port numbers are equivalent to those of this instance.
*/
public boolean equals(Object object) {
if (this == object) return true;
if (object == null || getClass() != object.getClass()) return false;
TCPConn conn = (TCPConn) object;
return (socket.getInetAddress().equals(conn.getInetAddress()) &&
socket.getPort() == conn.getPort() &&
socket.getLocalAddress().equals(conn.getLocalAddress()) &&
socket.getLocalPort() == conn.getLocalPort() ) ? true : false;
}
/** Returns code resulting from sum of remote and local address hashcodes and the remote port numbers.
* the local port is not included to uniquely id so as to allow only one server/client/port connection object in hashtable.
*/
public int hashCode() {
return socket.getInetAddress().hashCode() + socket.getLocalAddress().hashCode() + socket.getPort(); // + socket.getLocalPort();
}
/** Force closure of the socket streams. */
protected void finalize() {
this.close();
}
/** Returns a String summarizing labeled connection attributes. */
public String toString() {
return getSocketInfo();
}
/** Returns a String summarizing labeled connection attributes. */
public String getSocketInfo() {
if (socket == null) return "TCPConn socket is null.";
StringBuffer sb = new StringBuffer(512);
sb.append("TCPConn ");
sb.append(socket.toString());
sb.append("\n");
try {
sb.append(" Timeout MilliSecs : ");
sb.append(socket.getSoTimeout());
sb.append("\n");
sb.append(" Receive buffer size: ");
sb.append(socket.getReceiveBufferSize());
sb.append("\n");
sb.append(" Send buffer size : ");
sb.append(socket.getSendBufferSize());
sb.append("\n");
sb.append(" Tcp NoDelay : ");
sb.append(socket.getTcpNoDelay());
sb.append("\n");
sb.append(" Linger : ");
sb.append(socket.getSoLinger());
sb.append("\n");
/* java 1.3
sb.append(" KeepAlive : ");
sb.append(socket.getKeepAlive());
*/
}
catch (SocketException ex) {
ex.printStackTrace();
}
return sb.toString();
}
/** Convenience wrapper of System.out.println(getSocketInfo()).*/
public void print() {
System.out.println(getSocketInfo());
}
/** Sends specified number of bytes through socket output stream starting at specified offset.
* Does a no-op if output buffer has zero length.
* @exception java.io.IOException error occurred writing to the socket output stream, e.g. closed.
* @exception java.lang.NullPointerException buffer parameter is null
* @see #sendBuffer(byte[], int, int)
* @see #receiveBuffer(byte[], int)
* @see #receiveBuffer(byte[], int, int)
*/
public void sendBuffer(byte [] outBuffer) throws IOException {
if (outBuffer == null)
throw new NullPointerException("TCPConn.sendBuffer(byte[]) null buffer");
if (outBuffer.length == 0) return;
sendBuffer(outBuffer, 0, outBuffer.length);
}
/** Sends specified number of bytes through socket output stream starting at specified offset.
* @exception java.io.IOException error occurred writing to the socket output stream, e.g. closed.
* @exception java.lang.IndexOutOfBoundsException offset + bytesToSend> outBuffer.length.
* @exception java.lang.NullPointerException buffer parameter is null
* @see #sendBuffer(byte[])
* @see #receiveBuffer(byte[], int)
* @see #receiveBuffer(byte[], int, int)
*/
public void sendBuffer(byte [] outBuffer, int offset, int bytesToSend) throws IOException {
try {
socketOutStream.write(outBuffer, offset, bytesToSend);
}
catch (IOException ex) {
System.err.println("Error TCPConn.sendBuffer() Unable to send buffer, outbuffer.length: " +
outBuffer.length + " offset: " + offset + " bytesToSend: " + bytesToSend);
ex.fillInStackTrace();
throw ex;
}
}
/** Reads specified input number of bytes from socket input stream into input buffer.
* Returns bytes read or EOF if socket input times out after default timeout.
* @exception java.io.InterruptedIOException socket timedout while reading from the socket input stream.
* @exception java.io.IOException error occurred reading the socket input stream.
* @exception java.net.SocketException error occurred setting socket timeout attributes.
* @exception java.lang.NullPointerException buffer parameter is null
* @see #receiveBuffer(byte[], int, int)
*/
public int receiveBuffer(byte [] inBuffer) throws IOException {
return receiveBuffer(inBuffer, inBuffer.length, timeoutDefault);
}
/** Reads specified input number of bytes from socket input stream into input buffer.
* Returns bytes read or EOF if socket input times out after default timeout.
* @exception java.io.InterruptedIOException socket timedout while reading from the socket input stream.
* @exception java.io.IOException error occurred reading the socket input stream.
* @exception java.net.SocketException error occurred setting socket timeout attributes.
* @exception java.lang.IndexOutOfBoundsException inputLength > inBuffer.length.
* @exception java.lang.NullPointerException buffer parameter is null
* @see #receiveBuffer(byte[], int, int)
*/
public int receiveBuffer(byte [] inBuffer, int inputLength) throws IOException {
return receiveBuffer(inBuffer, inputLength, timeoutDefault);
}
/** Reads specified input number of bytes from socket input stream into input buffer.
* Returns bytes read or EOF if socket input times out after waiting the specified milliseconds.
* @exception java.io.InterruptedIOException socket timedout while reading from the socket input stream
* @exception java.io.IOException error occurred reading from the socket input stream.
* @exception java.net.SocketException error occurred setting socket timeout attributes.
* @exception java.lang.IndexOutOfBoundsException inputLength > inBuffer.length.
* @exception java.lang.NullPointerException buffer parameter is null
* @see #receiveBuffer(byte[], int)
*/
public int receiveBuffer(byte [] inBuffer, int inputLength, int timeoutMilliSecs) throws IOException {
if (inputLength > inBuffer.length)
throw new IndexOutOfBoundsException("TCPConn.receiveBuffer() inBuffer size < inputLength");
int bytesToRead = inputLength;
int bytesRead = 0;
int offset = 0;
try {
socket.setSoTimeout(timeoutMilliSecs);
while (bytesToRead > 0) {
bytesRead = socketInStream.read(inBuffer, offset, bytesToRead);
if (bytesRead > 0) {
bytesToRead -= bytesRead;
offset += bytesRead;
}
else if (bytesRead <= EOF) {
throw new IOException("TCPConn receiveBuffer socketInStream.read EOF ? socket closed.");
}
}
socket.setSoTimeout(timeoutDefault);
}
catch (InterruptedIOException ex) {
System.err.println("Error TCPConn.receiveBuffer() Socket timed out millisecs:" + timeoutMilliSecs +
" requested input length: " + inputLength + " bytes read: " + offset);
ex.fillInStackTrace();
throw ex;
}
catch (IOException ex) {
System.err.println("Error TCPConn.receiveBuffer() Unable to retrieve buffer, requested length: " + inputLength);
System.err.println(ex.getMessage());
ex.fillInStackTrace();
throw ex;
}
return offset;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -