All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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