net.alantea.socks.base.SocketEndPoint Maven / Gradle / Ivy
The newest version!
package net.alantea.socks.base;
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
import net.alantea.socks.base.exceptions.BadPortSocketError;
import net.alantea.socks.base.exceptions.ClosedSocketError;
import net.alantea.socks.base.exceptions.SocketError;
import net.alantea.socks.base.exceptions.UnconnectedSocketError;
import net.alantea.socks.base.exceptions.UninitializedSocketError;
// TODO: Auto-generated Javadoc
/**
* The Class SocketEndPoint. Simple base class
*/
public class SocketEndPoint
{
public static enum StartMethod
{
/** The Constant INITIALIZE_AS_SERVER. It means that the socket is prepared to be started in server mode.
* It is later needed to call waitForConnection(); to really start the server. */
INITIALIZE_AS_SERVER,
/** The Constant START_AS_SERVER_THREAD. It means that the socket is started in server mode. */
START_AS_SERVER_THREAD,
/** The Constant START_AS_SERVER. It means that the socket is started in server mode. */
START_AS_SERVER,
/** The Constant START_AS_CLIENT. It means that the socket is started in client mode. */
START_AS_CLIENT
};
/** The bad port number. */
private int BAD_PORT_NUMBER = -1;
/** The associated port number. */
private int numport = BAD_PORT_NUMBER;
/** The underlying socket server. */
private ServerSocket ss = null;
/** The associated socket. */
private Socket sock = null;
/** The associated output stream. */
private DataOutputStream dos = null;
/** The associated input stream. */
private BufferedInputStream dis = null;
/**
* Instantiates a new socket end point and start it.
*
* @param numport the numport
* @param startMethod starting method.
* @throws SocketError the socket error
*/
protected SocketEndPoint(int numport, StartMethod startMethod) throws SocketError
{
if (numport <= 0)
{
throw new BadPortSocketError("" + numport);
}
this.numport = numport;
switch(startMethod)
{
case INITIALIZE_AS_SERVER :
startServer(false);
break;
case START_AS_SERVER_THREAD :
startServer(false);
Thread thread = new Thread(() -> {
try
{
waitForNewConnection();
}
catch (SocketError e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("connected");
});
thread.setDaemon(true);
thread.start();
break;
case START_AS_SERVER :
startServer(true);
break;
case START_AS_CLIENT :
startClient();
break;
}
}
/**
* Start server side of the socket.
*
* @param waitForConnection wait for connection when starting if true
* @throws SocketError the socket error
*/
private void startServer(boolean waitForConnection) throws SocketError
{
// initialize socket
ss = null;
try
{
ss = new ServerSocket(numport);
}
catch (IOException e1)
{
throw new SocketError("startServer(" + numport + ")", e1);
}
if (waitForConnection)
{
waitForNewConnection();
}
}
/**
* Wait for a new connection. Close the current connection if already connected.
*
* @throws SocketError the socket error
*/
public void waitForNewConnection() throws SocketError
{
if ((sock != null) && (sock.isConnected()))
{
close();
}
try
{
sock = ss.accept();
openStreams();
}
catch (IOException e)
{
sock = null;
throw new SocketError("waitForConnection() on " + numport, e);
}
}
/**
* Start client side of the socket.
*
* @throws SocketError the socket error
*/
private void startClient() throws SocketError
{
// initialize socket
if (numport == BAD_PORT_NUMBER)
{
throw new SocketError("startClient() on " + numport);
}
if (sock != null)
{
return; // already opened. Continue...
}
// open socket
try
{
sock = new Socket("localhost", numport);
}
catch (MalformedURLException mue)
{
throw new SocketError("MalformedURLException in startClient() on " + numport, mue);
}
catch (IOException ioe)
{
throw new SocketError("IOException in startClient() on " + numport, ioe);
}
openStreams();
}
/**
* Open streams.
*
* @throws SocketError the socket error
*/
private void openStreams() throws SocketError
{
// open streams
try
{
dos = new DataOutputStream(sock.getOutputStream());
dis = new BufferedInputStream(sock.getInputStream());
}
catch (IOException ioe)
{
ioe.printStackTrace();
// close socket - problems opening it
try
{
sock.close();
}
catch (IOException e)
{
throw new SocketError("IOException in closing socket for openStreams() on " + numport, e);
}
throw new SocketError("IOException in openStreams() on " + numport, ioe);
}
}
/**
* Close connection.
*
* @throws SocketError the socket error
*/
public void close() throws SocketError
{
try
{
if (dos != null)
{
dos.close();
}
if (dis != null)
{
dis.close();
}
if (sock != null)
{
sock.close();
}
}
catch (IOException e)
{
throw new SocketError("IOException in close() on " + numport, e);
}
}
/**
* Checks if is closed.
*
* @return true, if is closed
*/
public boolean isClosed()
{
return (sock == null) ? true : sock.isClosed();
}
/**
* Checks if is connected.
*
* @return true, if is connected
*/
public boolean isConnected()
{
return (sock == null) ? false : sock.isConnected();
}
/**
* Get the number of available data to get.
*
* @return the int
* @throws SocketError the socket error
*/
public int available() throws SocketError
{
if (isClosed())
{
throw new ClosedSocketError("available()");
}
try
{
return dis.available();
}
catch (IOException e)
{
throw new SocketError("IOException in available() on " + numport, e);
}
}
/**
* Gets part of the socket content.
*
* @param size the size to get
* @return the byte[]
* @throws SocketError the socket error
*/
protected final byte[] getBytes(int size) throws SocketError
{
if (isClosed())
{
throw new ClosedSocketError("getBytes(" + size + ")");
}
try
{
// allocate buffer
byte[] bytes = new byte[size];
// read data
int nbr = dis.read(bytes);
while ((nbr > 0) && (nbr < size))
{
// wait until something comes here
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
// does not matter
}
int n = dis.read(bytes, nbr, size - nbr);
if ( n > 0 )
{
nbr += n;
}
}
return bytes;
}
catch (IOException e)
{
if (sock == null)
{
throw new UninitializedSocketError("getBytes(" + size + ")", e);
}
else if (! sock.isConnected())
{
throw new UnconnectedSocketError("getBytes(" + size + ")", e);
}
else if (sock.isClosed())
{
throw new ClosedSocketError("getBytes(" + size + ")");
}
else
{
throw new SocketError("getBytes(" + size + ")", e);
}
}
}
/**
* Push an information.
*
* @param content the content
* @throws SocketError the socket error
*/
protected final void pushBytes(byte[] content) throws SocketError
{
// open socket if it has been closed
if ( sock == null)
{
throw new UninitializedSocketError("pushBytes(...)");
}
// write buffer
try
{
dos.write(content);
dos.flush();
}
catch (IOException e)
{
e.printStackTrace();
throw new SocketError(e.getMessage());
}
}
/**
* Gets the port nummber.
*
* @return the port nummber
*/
public int getPortNumber()
{
return numport;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy