From cf66d68c005978b6185b90d4f140d052ce00faf2 Mon Sep 17 00:00:00 2001 From: Rik Veenboer Date: Sun, 26 Apr 2015 11:34:13 +0100 Subject: [PATCH] Initial work on worker based udp/tcp client/server implementations --- .../main/java/base/server/AbstractClient.java | 17 +++++ .../src/main/java/base/server/TcpClient.java | 53 +++++++++++++++ .../src/main/java/base/server/TcpServer.java | 68 +++++++++++++++++++ .../src/main/java/base/server/UdpServer.java | 55 +++++++++++++++ 4 files changed, 193 insertions(+) create mode 100644 java/base/src/main/java/base/server/AbstractClient.java create mode 100644 java/base/src/main/java/base/server/TcpClient.java create mode 100644 java/base/src/main/java/base/server/TcpServer.java create mode 100644 java/base/src/main/java/base/server/UdpServer.java diff --git a/java/base/src/main/java/base/server/AbstractClient.java b/java/base/src/main/java/base/server/AbstractClient.java new file mode 100644 index 0000000..b601b84 --- /dev/null +++ b/java/base/src/main/java/base/server/AbstractClient.java @@ -0,0 +1,17 @@ +package base.server; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; + +import base.worker.Worker; + +public abstract class AbstractClient extends Worker { + protected Socket socket; + protected InputStream inputStream; + protected OutputStream outputStream; + + public AbstractClient(Socket socket) { + this.socket = socket; + } +} diff --git a/java/base/src/main/java/base/server/TcpClient.java b/java/base/src/main/java/base/server/TcpClient.java new file mode 100644 index 0000000..41468e1 --- /dev/null +++ b/java/base/src/main/java/base/server/TcpClient.java @@ -0,0 +1,53 @@ +package base.server; + +import java.io.IOException; +import java.net.Socket; +import java.net.UnknownHostException; + +import base.exception.worker.ActivateException; +import base.exception.worker.DeactivateException; + +public abstract class TcpClient extends AbstractClient { + protected String host; + protected int port; + + public TcpClient(String ip, int port) { + super(null); + this.host = ip; + this.port = port; + } + + public void activate() throws ActivateException { + try { + socket = new Socket(host, port); + socket.setSoTimeout(SLEEP); + inputStream = socket.getInputStream(); + outputStream = socket.getOutputStream(); + } catch (UnknownHostException e) { + logger.error("", e); + throw new ActivateException(); + } catch (IOException e) { + logger.error("", e); + throw new ActivateException(); + } + super.activate(); + } + + public synchronized boolean active() { + if (active && !socket.isConnected()) { + active = false; + } + return active; + } + + public void deactivate() throws DeactivateException { + super.deactivate(); + try { + inputStream.close(); + outputStream.close(); + socket.close(); + } catch (IOException e) { + logger.error("", e); + } + } +} \ No newline at end of file diff --git a/java/base/src/main/java/base/server/TcpServer.java b/java/base/src/main/java/base/server/TcpServer.java new file mode 100644 index 0000000..c98649d --- /dev/null +++ b/java/base/src/main/java/base/server/TcpServer.java @@ -0,0 +1,68 @@ +package base.server; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; + +import base.exception.worker.ActivateException; +import base.worker.Worker; + +public class TcpServer extends Worker { + protected int port; + protected Socket socket; + protected Constructor clientConstructor; + protected ArrayList clientList; + protected ServerSocket serverSocket; + + public TcpServer(int port, Class clientClass) { + this.port = port; + try { + clientConstructor = Class.forName(clientClass.getName()).getConstructor(Socket.class); + } catch (NoSuchMethodException | SecurityException | ClassNotFoundException e) { + logger.error("Failed to initialise client constructor"); + } + clientList = new ArrayList(); + } + + protected void activate() throws ActivateException { + try { + serverSocket = new ServerSocket(port); + } catch (IOException e) { + logger.error("", e); + throw new ActivateException(); + } + super.activate(); + } + + public void work() { + try { + socket = serverSocket.accept(); + } catch (IOException e) { + logger.error("", e); + return; + } + try { + Client client = (Client) clientConstructor.newInstance(socket); + clientList.add(client); + client.start(); + } catch (Exception e) { + logger.error("", e); + } + } + + public static abstract class Client extends AbstractClient { + + public Client(Socket socket) { + super(socket); + } + + public void setSocket(Socket socket) { + } + + public void work() { + } + } + +} diff --git a/java/base/src/main/java/base/server/UdpServer.java b/java/base/src/main/java/base/server/UdpServer.java new file mode 100644 index 0000000..ac226de --- /dev/null +++ b/java/base/src/main/java/base/server/UdpServer.java @@ -0,0 +1,55 @@ +package base.server; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.SocketException; + +import base.exception.worker.ActivateException; +import base.worker.Worker; + +public abstract class UdpServer extends Worker { + protected static final int BUFFER_SIZE = 1024; + protected int port; + protected int bufferSize; + protected DatagramSocket diagramSocket; + + public UdpServer(int port) { + this(port, BUFFER_SIZE); + } + + public UdpServer(int port, int bufferSize) { + this.port = port; + this.bufferSize = bufferSize; + } + + protected void activate() throws ActivateException { + try { + logger.debug("Starting datagram socket on port " + port); + diagramSocket = new DatagramSocket(port); + super.activate(); + } catch (SocketException e) { + logger.error("Failed to initialize socket", e); + throw new ActivateException(); + } + } + + public void work() { + byte[] buffer = new byte[bufferSize]; + DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length); + try { + diagramSocket.receive(datagramPacket); + } catch (IOException e) { + logger.error("Failed to receive packet"); + stop(); + return; + } + receive(buffer); + } + + public synchronized void stop() { + diagramSocket.close(); + } + + abstract protected void receive(byte[] buffer); +}