From 0c3e1425fdf352cd6f3a7264660f7214c76140da Mon Sep 17 00:00:00 2001 From: Marc Baloup Date: Sat, 8 Feb 2020 15:43:19 +0100 Subject: [PATCH] Full refactor of network API + deprecation of old API --- .../packet/bytebuffer => net}/Array8Bit.java | 15 +- .../packet/bytebuffer => net}/ByteBuffer.java | 97 ++--- .../java/fr/pandacube/util/net/PPacket.java | 57 +++ .../fr/pandacube/util/net/PPacketAnswer.java | 44 +++ .../pandacube/util/net/PPacketListener.java | 13 + .../java/fr/pandacube/util/net/PServer.java | 165 ++++++++ .../java/fr/pandacube/util/net/PSocket.java | 351 +++++++++++++++++ .../util/net/PSocketConnectionListener.java | 17 + .../util/network/client/TCPClient.java | 224 ----------- .../network/client/TCPClientListener.java | 42 --- .../pandacube/util/network/packet/Packet.java | 118 ------ .../util/network/packet/PacketClient.java | 13 - .../util/network/packet/PacketException.java | 24 -- .../util/network/packet/PacketServer.java | 13 - .../util/network/packet/ResponseCallback.java | 8 - .../packet/bytebuffer/ByteSerializable.java | 19 - .../Packet30ClientDeclareProcess.java | 39 -- .../core_slave/Packet31ClientClose.java | 22 -- .../Packet32ClientProcessQueryResponse.java | 61 --- .../core_slave/PacketB0ServerClose.java | 22 -- ...cketB1ServerProcessDeclarationConfirm.java | 32 -- .../PacketB2ServerConnectSuccess.java | 22 -- .../PacketB3ServerProcessInput.java | 42 --- .../PacketB4ServerProcessQuery.java | 73 ---- .../global/Packet50ClientAuthenticate.java | 35 -- .../global/Packet51ClientLogRecord.java | 76 ---- .../global/PacketD0ServerException.java | 38 -- .../PacketD1ServerCantAuthenticate.java | 20 - .../packets/global/PacketD2ServerCommand.java | 30 -- .../packets/web/Packet00ClientWebRequest.java | 43 --- .../web/Packet80ServerWebResponse.java | 32 -- .../network/server/BandwidthCalculation.java | 56 --- .../util/network/server/TCPServer.java | 355 ------------------ .../network/server/TCPServerListener.java | 19 - .../network_api/client/AbstractRequest.java | 1 + .../network_api/client/NetworkAPISender.java | 1 + .../network_api/client/ResponseAnalyser.java | 1 + .../server/AbstractRequestExecutor.java | 1 + .../server/NAPIExecutionHandler.java | 14 - .../server/NetworkAPIListener.java | 9 +- .../network_api/server/PacketExecutor.java | 1 + .../network_api/server/RequestAnalyser.java | 1 + .../util/network_api/server/Response.java | 1 + .../server/ThreadNAPIExecutionHandler.java | 12 - 44 files changed, 684 insertions(+), 1595 deletions(-) rename src/main/java/fr/pandacube/util/{network/packet/bytebuffer => net}/Array8Bit.java (76%) rename src/main/java/fr/pandacube/util/{network/packet/bytebuffer => net}/ByteBuffer.java (66%) create mode 100644 src/main/java/fr/pandacube/util/net/PPacket.java create mode 100644 src/main/java/fr/pandacube/util/net/PPacketAnswer.java create mode 100644 src/main/java/fr/pandacube/util/net/PPacketListener.java create mode 100644 src/main/java/fr/pandacube/util/net/PServer.java create mode 100644 src/main/java/fr/pandacube/util/net/PSocket.java create mode 100644 src/main/java/fr/pandacube/util/net/PSocketConnectionListener.java delete mode 100644 src/main/java/fr/pandacube/util/network/client/TCPClient.java delete mode 100644 src/main/java/fr/pandacube/util/network/client/TCPClientListener.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/Packet.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/PacketClient.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/PacketException.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/PacketServer.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/ResponseCallback.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/bytebuffer/ByteSerializable.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/core_slave/Packet30ClientDeclareProcess.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/core_slave/Packet31ClientClose.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/core_slave/Packet32ClientProcessQueryResponse.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB0ServerClose.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB1ServerProcessDeclarationConfirm.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB2ServerConnectSuccess.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB3ServerProcessInput.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB4ServerProcessQuery.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/global/Packet50ClientAuthenticate.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/global/Packet51ClientLogRecord.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/global/PacketD0ServerException.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/global/PacketD1ServerCantAuthenticate.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/global/PacketD2ServerCommand.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/web/Packet00ClientWebRequest.java delete mode 100644 src/main/java/fr/pandacube/util/network/packet/packets/web/Packet80ServerWebResponse.java delete mode 100644 src/main/java/fr/pandacube/util/network/server/BandwidthCalculation.java delete mode 100644 src/main/java/fr/pandacube/util/network/server/TCPServer.java delete mode 100644 src/main/java/fr/pandacube/util/network/server/TCPServerListener.java delete mode 100644 src/main/java/fr/pandacube/util/network_api/server/NAPIExecutionHandler.java delete mode 100644 src/main/java/fr/pandacube/util/network_api/server/ThreadNAPIExecutionHandler.java diff --git a/src/main/java/fr/pandacube/util/network/packet/bytebuffer/Array8Bit.java b/src/main/java/fr/pandacube/util/net/Array8Bit.java similarity index 76% rename from src/main/java/fr/pandacube/util/network/packet/bytebuffer/Array8Bit.java rename to src/main/java/fr/pandacube/util/net/Array8Bit.java index 8e5e9b3..8a3c22a 100644 --- a/src/main/java/fr/pandacube/util/network/packet/bytebuffer/Array8Bit.java +++ b/src/main/java/fr/pandacube/util/net/Array8Bit.java @@ -1,8 +1,8 @@ -package fr.pandacube.util.network.packet.bytebuffer; +package fr.pandacube.util.net; import java.util.Arrays; -public class Array8Bit implements ByteSerializable { +public class Array8Bit { public static final int BIT_COUNT = Byte.SIZE; @@ -63,15 +63,4 @@ public class Array8Bit implements ByteSerializable { - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - fromByte(buffer.getByte()); - } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - buffer.putByte(toByte()); - } - - } diff --git a/src/main/java/fr/pandacube/util/network/packet/bytebuffer/ByteBuffer.java b/src/main/java/fr/pandacube/util/net/ByteBuffer.java similarity index 66% rename from src/main/java/fr/pandacube/util/network/packet/bytebuffer/ByteBuffer.java rename to src/main/java/fr/pandacube/util/net/ByteBuffer.java index 38c4745..80dac7f 100644 --- a/src/main/java/fr/pandacube/util/network/packet/bytebuffer/ByteBuffer.java +++ b/src/main/java/fr/pandacube/util/net/ByteBuffer.java @@ -1,27 +1,32 @@ -package fr.pandacube.util.network.packet.bytebuffer; +package fr.pandacube.util.net; -import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -public class ByteBuffer implements Cloneable { +import fr.pandacube.Pandacube; + +public final class ByteBuffer implements Cloneable { private java.nio.ByteBuffer buff; - private Charset charset; - public ByteBuffer(Charset c) { - this(16, c); + public ByteBuffer() { + this(16); } - public ByteBuffer(int initSize, Charset c) { + public ByteBuffer(int initSize) { buff = java.nio.ByteBuffer.allocate(initSize); - charset = c; } - public ByteBuffer(byte[] data, Charset c) { - buff = java.nio.ByteBuffer.wrap(Arrays.copyOf(data, data.length)); - charset = c; + /** + * Create a ByteBuffer that is initially backed by the provided byte array. + * The position of this buffer will be 0. + * If this ByteBuffer needs a biffer array, the provided array is replaced by a new one, + * making the provided array not related to this ByteBuffer anymore. + * @param data array of byte that serve as a backend for this ByteBuffer. + */ + public ByteBuffer(byte[] data) { + buff = java.nio.ByteBuffer.wrap(data); } private void askForBufferExtension(int needed) { @@ -32,9 +37,12 @@ public class ByteBuffer implements Cloneable { } } + /** + * This clone method also clone the underlying array. + */ @Override public ByteBuffer clone() { - return new ByteBuffer(Arrays.copyOf(buff.array(), buff.array().length), charset); + return new ByteBuffer(Arrays.copyOf(buff.array(), buff.array().length)); } /** @@ -215,7 +223,7 @@ public class ByteBuffer implements Cloneable { if (s == null) { return putInt(-1); } - return putSizedByteArray(s.getBytes(charset)); + return putSizedByteArray(s.getBytes(Pandacube.NETWORK_CHARSET)); } /** @@ -224,51 +232,7 @@ public class ByteBuffer implements Cloneable { */ public String getString() { byte[] binaryString = getSizedByteArray(); - return (binaryString == null) ? null : new String(binaryString, charset); - } - - /** - * The objet will be serialized and the data put in the current buffer - * - * @param obj the object to serialize. Can't be null. - * @return the current buffer - */ - public ByteBuffer putObject(ByteSerializable obj) { - obj.serializeToByteBuffer(this); - return this; - } - - /** - * Ask to object passed as argument to deserialize data in buffer and fill - * the object content. ByteSerializable object are never null. - * - * @param - * @param clazz the class wich will be instanciated with his no-argument Constructor - * before filled by using {@link ByteSerializable#deserializeFromByteBuffer(ByteBuffer)} - * @return obj a reference to the filled object - */ - public T getObject(Class clazz) { - try { - T obj = clazz.newInstance(); - obj.deserializeFromByteBuffer(this); - return obj; - } catch (InstantiationException | IllegalAccessException e) { - throw new RuntimeException("A ByteSerializable must have a no-argument Constructor", e); - } - } - - /** - * - * @param list The list itself can be null, but not the values. - * @return - */ - public ByteBuffer putListObject(List list) { - if (list.stream().anyMatch(e -> e == null)) - throw new IllegalArgumentException("List of object can't contains any null value"); - putInt(list.size()); - for (ByteSerializable obj : list) - putObject(obj); - return this; + return (binaryString == null) ? null : new String(binaryString, Pandacube.NETWORK_CHARSET); } /** @@ -286,25 +250,10 @@ public class ByteBuffer implements Cloneable { return this; } - /** - * - * @param clazz - * @return Can be null. If not, there is no null element inside. - */ - public List getListObject(Class clazz) { - int size = getInt(); - if (size < 0) - return null; - List list = new ArrayList<>(); - for (int i = 0; i < size; i++) - list.add(getObject(clazz)); - return list; - } - /** * @return a List of String. The list can be null, and any element can be null too. */ - public List getListOfString() { + public List getListOfString() { int size = getInt(); if (size < 0) return null; diff --git a/src/main/java/fr/pandacube/util/net/PPacket.java b/src/main/java/fr/pandacube/util/net/PPacket.java new file mode 100644 index 0000000..635e968 --- /dev/null +++ b/src/main/java/fr/pandacube/util/net/PPacket.java @@ -0,0 +1,57 @@ +package fr.pandacube.util.net; + +import java.util.Arrays; + +public class PPacket { + public String name; + /* package */ int id; + public byte[] content; + + /** + * Construct a new PPacket based on the content of the provided buffer before his position. + * @param n the name of the packet. + * @param buff the buffer where the data comes from. Only the content before {@link ByteBuffer#getPosition()} is copied. + */ + public PPacket(String n, ByteBuffer buff) { + this(n, Arrays.copyOf(buff.array(), buff.getPosition())); + } + + public PPacket(String n, byte[] c) { + name = n; + content = c; + } + + /* package */ PPacket(String n, int i, byte[] c) { + this(n, c); + id = i; + } + + public ByteBuffer getContentAsBuffer() { + return new ByteBuffer(content); + } + + + + + + + + + public static PPacket buildSingleStringContentPacket(String name, String content) { + return new PPacket(name, new ByteBuffer().putString(content)); + } + + + + + + /* package */ static PPacket buildLoginPacket(String password) { + return buildSingleStringContentPacket("login", password); + } + /* package */ static PPacket buildBadFormatPacket(String message) { + return buildSingleStringContentPacket("bad_format", message); + } + /* package */ static PPacket buildLoginBadPacket() { + return new PPacket("login_bad", new byte[0]); + } +} diff --git a/src/main/java/fr/pandacube/util/net/PPacketAnswer.java b/src/main/java/fr/pandacube/util/net/PPacketAnswer.java new file mode 100644 index 0000000..308678d --- /dev/null +++ b/src/main/java/fr/pandacube/util/net/PPacketAnswer.java @@ -0,0 +1,44 @@ +package fr.pandacube.util.net; + +import java.util.Arrays; + +public class PPacketAnswer extends PPacket { + /* package */ int answer; + + /** + * Construct a new PPacketAnswer based on the content of the provided buffer before his position. + * @param n the name of the packet. + * @param buff the buffer where the data comes from. Only the content before {@link ByteBuffer#getPosition()} is copied. + */ + public PPacketAnswer(PPacket answered, String n, ByteBuffer buff) { + this(answered, n, Arrays.copyOf(buff.array(), buff.getPosition())); + } + + public PPacketAnswer(PPacket answered, String n, byte[] c) { + super(n, c); + answer = answered.id; + } + + /* package */ PPacketAnswer(String n, int i, int a, byte[] c) { + super(n, i, c); + answer = a; + } + + + + + public static PPacketAnswer buildSingleStringContentPacketAnswer(PPacket answered, String name, String content) { + ByteBuffer pwBuff = new ByteBuffer().putString(content); + return new PPacketAnswer(answered, name, Arrays.copyOf(pwBuff.array(), pwBuff.getPosition())); + } + + + + + /* package */ static PPacketAnswer buildLoginOkPacket(PPacket loginPacket) { + return new PPacketAnswer(loginPacket, "login_ok", new byte[0]); + } + /* package */ static PPacketAnswer buildExceptionPacket(PPacket answered, String message) { + return buildSingleStringContentPacketAnswer(answered, "exception", message); + } +} diff --git a/src/main/java/fr/pandacube/util/net/PPacketListener.java b/src/main/java/fr/pandacube/util/net/PPacketListener.java new file mode 100644 index 0000000..bd88f4f --- /dev/null +++ b/src/main/java/fr/pandacube/util/net/PPacketListener.java @@ -0,0 +1,13 @@ +package fr.pandacube.util.net; + +@FunctionalInterface +public interface PPacketListener

{ + + /** + * Called when we receive a packet (except responses) + * @param connection the connection from where the packet comes + * @param packet the received packet + */ + public void onPacketReceive(PSocket connection, P packet); + +} diff --git a/src/main/java/fr/pandacube/util/net/PServer.java b/src/main/java/fr/pandacube/util/net/PServer.java new file mode 100644 index 0000000..9551612 --- /dev/null +++ b/src/main/java/fr/pandacube/util/net/PServer.java @@ -0,0 +1,165 @@ +package fr.pandacube.util.net; + +import java.io.Closeable; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import fr.pandacube.Pandacube; +import fr.pandacube.util.Log; + +public class PServer extends Thread implements Closeable { + private static AtomicInteger connectionCounterId = new AtomicInteger(0); + + private int port; + private ServerSocket socket; + private String socketName; + + private List clients = Collections.synchronizedList(new ArrayList<>()); + + private AtomicBoolean isClosed = new AtomicBoolean(false); + + + private List> globalPacketListeners = Collections.synchronizedList(new ArrayList<>()); + private List clientConnectionListeners = Collections.synchronizedList(new ArrayList<>()); + + + + private String password; + + public PServer(int port, String sckName, String password) throws IOException { + super("PServer " + sckName); + setDaemon(true); + if (port <= 0 || port > 65535) throw new IllegalArgumentException("le numéro de port est invalide"); + socketName = sckName; + this.port = port; + this.password = password; + } + + @Override + public void run() { + + try { + + socket = new ServerSocket(); + socket.setReceiveBufferSize(Pandacube.NETWORK_TCP_BUFFER_SIZE); + socket.setPerformancePreferences(0, 1, 0); + socket.bind(new InetSocketAddress(port)); + + while (true) { + Socket socketClient = socket.accept(); + socketClient.setSendBufferSize(Pandacube.NETWORK_TCP_BUFFER_SIZE); + socketClient.setSoTimeout(Pandacube.NETWORK_TIMEOUT); + + try { + @SuppressWarnings("resource") + TCPServerClientConnection co = new TCPServerClientConnection(socketClient, + connectionCounterId.getAndIncrement()); + co.start(); + } catch (IOException e) { + Log.severe("Connexion impossible avec " + socketClient.getInetAddress()); + } + } + } catch(SocketException e) { + + } catch (Exception e) { + Log.warning("Plus aucune connexion ne peux être acceptée", e); + } + } + + + + public void addPacketListener(PPacketListener l) { + globalPacketListeners.add(l); + } + + public boolean removePacketListener(PPacketListener l) { + return globalPacketListeners.remove(l); + } + + public void addConnectionListener(PSocketConnectionListener l) { + clientConnectionListeners.add(l); + } + + public void removeConnectionListener(PSocketConnectionListener l) { + clientConnectionListeners.remove(l); + } + + protected class TCPServerClientConnection extends PSocket { + + boolean loggedIn; + + private TCPServerClientConnection(Socket s, int coId) throws IOException { + super(s, "Conn#" + coId + " via TCPSv " + socketName, password); + addConnectionListener(new PSocketConnectionListener() { + @Override + public void onDisconnect(PSocket connection) { + try { + clientConnectionListeners.forEach(l -> l.onDisconnect(connection)); + } finally { + clients.remove((TCPServerClientConnection)connection); + } + } + @Override + public void onConnect(PSocket connection) { + clients.add((TCPServerClientConnection)connection); + clientConnectionListeners.forEach(l -> l.onConnect(connection)); + } + }); + addPacketListener((conn, packet) -> { + globalPacketListeners.forEach(l -> { + try { + l.onPacketReceive(conn, packet); + } catch (Exception e) { + Log.severe("Exception while calling PPacketListener.onPacketReceive().", e); + sendSilently(PPacketAnswer.buildExceptionPacket(packet, e.toString())); + } + }); + }); + } + + } + + @Override + public void close() { + try { + if (isClosed.get()) return; + isClosed.set(true); + + clients.forEach(PSocket::close); + + socket.close(); + } catch (IOException e) {} + } + + public boolean isClosed() { + return isClosed.get() || socket.isClosed(); + } + + + + public List getClients() { + synchronized (clients) { + return new ArrayList<>(clients); + } + } + + + + @Override + public String toString() { + return new ToStringBuilder(this) + .append("thread", getName()) + .append("socket", socket).toString(); + } + +} diff --git a/src/main/java/fr/pandacube/util/net/PSocket.java b/src/main/java/fr/pandacube/util/net/PSocket.java new file mode 100644 index 0000000..4ef0e7b --- /dev/null +++ b/src/main/java/fr/pandacube/util/net/PSocket.java @@ -0,0 +1,351 @@ +package fr.pandacube.util.net; + +import java.io.BufferedOutputStream; +import java.io.Closeable; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketAddress; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.google.common.base.Objects; + +import fr.pandacube.Pandacube; +import fr.pandacube.util.Log; + +/** + * A wrapper for a {@link Socket}. The connection must point to a software using {@link PServer} + * as wrapper for the target {@link ServerSocket}. + *
+ * This class provides a simple way to exchange data between client and server : + *

  • Maintained connection with the server
  • + *
  • Login with a password (send in the first packet)
  • + *
  • Named packets
  • + *
  • Binary data
  • + *
  • Input stream in a separate Thread
  • + * + */ +public class PSocket extends Thread implements Closeable { + + private boolean server = false; + private Socket socket; + private SocketAddress addr; + private DataInputStream in; + private DataOutputStream out; + private Object outSynchronizer = new Object(); + private String password; + + private AtomicBoolean isClosed = new AtomicBoolean(false); + + private List> packetListeners = Collections.synchronizedList(new ArrayList<>()); + private List connectionListeners = Collections.synchronizedList(new ArrayList<>()); + private Map> answersCallbacks = Collections.synchronizedMap(new HashMap<>()); + + private int nextSendId = 0; + + /** + * Create a new PSocket that will connect to the specified SocketAddress. + * @param a The target server to connect to + * @param connName the name of the connection, used to name the Thread used to receive the packet. + * @param the password to send to the server. + */ + public PSocket(SocketAddress a, String connName, String pass) { + super("PSocket " + connName); + setDaemon(true); + if (a == null) throw new IllegalArgumentException("les arguments ne peuvent pas être null"); + addr = a; + } + + + /* package */ PSocket(Socket s, String connName, String pass) { + this(s.getRemoteSocketAddress(), connName, pass); + socket = s; + server = true; + } + + + + @Override + public void run() { + + try { + if (socket == null) { + socket = new Socket(); + socket.setReceiveBufferSize(Pandacube.NETWORK_TCP_BUFFER_SIZE); + socket.setSendBufferSize(Pandacube.NETWORK_TCP_BUFFER_SIZE); + + socket.setSoTimeout(10000); // initial timeout before login + + socket.connect(addr); + + in = new DataInputStream(socket.getInputStream()); + out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); + } + + // password check + if (server) { + PPacket packet = readPacket(); + if (packet == null || packet instanceof PPacketAnswer || !"login".equals(packet.name)) { + send(PPacket.buildLoginBadPacket()); + close(); + return; + } + try { + String receivedPassword = new ByteBuffer(packet.content).getString(); + if (!Objects.equal(receivedPassword, password)) { + send(PPacket.buildLoginBadPacket()); + close(); + return; + } + } catch(Exception e) { + send(PPacket.buildLoginBadPacket()); + close(); + return; + } + send(PPacketAnswer.buildLoginOkPacket(packet)); + // login ok at this point + password = null; + } + else { + send(PPacket.buildLoginPacket(password)); + PPacket packet = readPacket(); + if (packet == null) { + Log.severe("bad packet received from server. Disconnecting."); + close(); + return; + } + if (packet.name.equals("login_bad")) { + Log.severe("Wrong password to connect to server. Disconnecting."); + close(); + return; + } + if (!packet.name.equals("login_ok")) { + Log.severe("Unexpected packet from server. Disconnecting."); + close(); + return; + } + // login ok at this point + password = null; + } + + socket.setSoTimeout(Pandacube.NETWORK_TIMEOUT); + + Log.info(getName() + " connected."); + + connectionListeners.forEach(l -> { + try { + l.onConnect(this); + } catch (Exception e) { + Log.severe("Exception while calling PSocketConnectionListener.onConnect().", e); + } + }); + + while (!socket.isClosed()) { + PPacket packet = readPacket(); + + if (packet == null) { + send(PPacket.buildBadFormatPacket("Bad format for the last packet received. Closing connection.")); + break; + } + + if (packet instanceof PPacketAnswer) { + try { + answersCallbacks.remove(((PPacketAnswer)packet).answer).onPacketReceive(this, (PPacketAnswer)packet); + } catch (Exception e) { + Log.severe("Exception while calling PPacketListener.onPacketReceive().", e); + send(PPacketAnswer.buildExceptionPacket(packet, e.toString())); + } + } + else { + packetListeners.forEach(l -> { + try { + l.onPacketReceive(this, packet); + } catch (Exception e) { + Log.severe("Exception while calling PPacketListener.onPacketReceive().", e); + sendSilently(PPacketAnswer.buildExceptionPacket(packet, e.toString())); + } + }); + } + } + + } catch (Exception e) { + Log.severe(e); + } + close(); + } + + + /** + * Return the packet read in the socket, or null if the packet is in a bad format. + * @return the packet + * @throws IOException + * + */ + private PPacket readPacket() throws IOException { + byte nSize = in.readByte(); + if (nSize == 0) { + return null; + } + boolean answer = nSize < 0; + if (answer) + nSize *= -1; + + + byte[] nBytes = new byte[nSize]; + in.readFully(nBytes); + String name = new String(nBytes, Pandacube.NETWORK_CHARSET); + + + int packetId = in.readInt(); + + + int answerId = (answer) ? in.readInt() : -1; + + + int cSize = in.readInt(); + if (cSize < 0 || cSize > 0xFFFFFF) { // can't be more that 16 MiB + return null; + } + + + byte[] content = new byte[cSize]; + in.readFully(content); + + return answer ? new PPacketAnswer(name, packetId, answerId, content) : new PPacket(name, packetId, content); + } + + + + + + + /** + * Send the provided packet, without waiting for an answer. + * @param packet + * @throws IOException + */ + public void send(PPacket packet) throws IOException { + if (packet == null) + throw new IllegalArgumentException("packet can't be null"); + if (packet.name == null) + throw new IllegalArgumentException("packet.name can't be null"); + if (packet.content == null) + throw new IllegalArgumentException("packet.content can't be null"); + + byte[] nameBytes = packet.name.getBytes(Pandacube.NETWORK_CHARSET); + if (nameBytes.length > 127) + throw new IllegalArgumentException("packet.name must take fewer than 128 bytes when converted to UTF-8"); + byte nameSize = (byte)nameBytes.length; + + boolean answer = packet instanceof PPacketAnswer; + + if (answer) nameSize *= -1; + + synchronized (outSynchronizer) { + int packetId = nextSendId++; + + packet.id = packetId; + + out.write(new byte[] {nameSize}); + out.write(nameBytes); + out.write(packetId); + if (answer) + out.write(((PPacketAnswer)packet).answer); + out.write(packet.content.length); + out.write(packet.content); + out.flush(); + } + } + + public void sendSilently(PPacket packet) { + try { + send(packet); + } catch (IOException e) {} + } + + + + public void send(PPacket packet, PPacketListener answerCallback) throws IOException { + synchronized (answersCallbacks) { + /* + * This synch block ensure that the callback will be put in the listeners Map before + * we receve the answer (in case this is really really fast) + */ + send(packet); + answersCallbacks.put(packet.id, answerCallback); + } + } + + + + + + + + + public void addPacketListener(PPacketListener l) { + packetListeners.add(l); + } + + public boolean removePacketListener(PPacketListener l) { + return packetListeners.remove(l); + } + + + public void addConnectionListener(PSocketConnectionListener l) { + connectionListeners.add(l); + } + + public void removeConnectionListener(PSocketConnectionListener l) { + connectionListeners.remove(l); + } + + @Override + public void close() { + try { + synchronized (outSynchronizer) { + if (isClosed.get()) return; + + Log.info(getName() + " closing..."); + + connectionListeners.forEach(l -> { + try { + l.onDisconnect(this); + } catch (Exception e) { + Log.severe("Exception while calling PSocketConnectionListener.onDisconnect().", e); + } + }); + + socket.close(); + isClosed.set(true); + } + } catch (IOException e) { + Log.warning(e); + } + } + + public SocketAddress getRemoteAddress() { + return addr; + } + + public boolean isClosed() { + return isClosed.get() || socket.isClosed(); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .append("thread", getName()) + .append("socket", socket.getRemoteSocketAddress()).toString(); + } + +} diff --git a/src/main/java/fr/pandacube/util/net/PSocketConnectionListener.java b/src/main/java/fr/pandacube/util/net/PSocketConnectionListener.java new file mode 100644 index 0000000..db4d865 --- /dev/null +++ b/src/main/java/fr/pandacube/util/net/PSocketConnectionListener.java @@ -0,0 +1,17 @@ +package fr.pandacube.util.net; + +public interface PSocketConnectionListener { + + /** + * Called when a socket is connected + * @param connection the connection + */ + public void onConnect(PSocket connection); + + /** + * Called just before a socket is disconnected + * @param connection the connection + */ + public void onDisconnect(PSocket connection); + +} diff --git a/src/main/java/fr/pandacube/util/network/client/TCPClient.java b/src/main/java/fr/pandacube/util/network/client/TCPClient.java deleted file mode 100644 index 0ba6877..0000000 --- a/src/main/java/fr/pandacube/util/network/client/TCPClient.java +++ /dev/null @@ -1,224 +0,0 @@ -package fr.pandacube.util.network.client; - -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketAddress; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Predicate; - -import org.apache.commons.lang.builder.ToStringBuilder; -import org.javatuples.Pair; - -import fr.pandacube.Pandacube; -import fr.pandacube.util.Log; -import fr.pandacube.util.network.packet.Packet; -import fr.pandacube.util.network.packet.PacketClient; -import fr.pandacube.util.network.packet.PacketException; -import fr.pandacube.util.network.packet.PacketServer; -import fr.pandacube.util.network.packet.ResponseCallback; -import fr.pandacube.util.network.packet.packets.global.PacketD0ServerException; - -public class TCPClient extends Thread implements Closeable { - - private Socket socket; - private SocketAddress addr; - private TCPClientListener listener; - private InputStream in; - private OutputStream out; - private Object outSynchronizer = new Object(); - private List, ResponseCallback>> callbacks = Collections.synchronizedList(new ArrayList<>()); - private List, ResponseCallback>> callbacksAvoidListener = Collections.synchronizedList(new ArrayList<>()); - - private AtomicBoolean isClosed = new AtomicBoolean(false); - - public TCPClient(InetSocketAddress a, String connName, TCPClientListener l) throws IOException { - super("TCPCl " + connName); - setDaemon(true); - if (a == null || l == null) throw new IllegalArgumentException("les arguments ne peuvent pas être null"); - socket = new Socket(); - socket.setReceiveBufferSize(Pandacube.NETWORK_TCP_BUFFER_SIZE); - socket.setSendBufferSize(Pandacube.NETWORK_TCP_BUFFER_SIZE); - socket.setSoTimeout(Pandacube.NETWORK_TIMEOUT); - socket.connect(a); - addr = a; - listener = l; - try { - listener.onConnect(this); - } catch (Exception e) { - Log.severe("Exception while calling TCPClientListener.onConnect()", e); - } - } - - @Override - public void run() { - - try { - byte[] code = new byte[1]; - while (!socket.isClosed() && in.read(code) != -1) { - byte[] sizeB = new byte[4]; - if (in.read(sizeB) != 4) throw new IOException("Socket " + addr + " fermé"); - - int size = ByteBuffer.wrap(sizeB).getInt(); - - byte[] content = new byte[size]; - - forceReadBytes(content); - - byte[] packetData = ByteBuffer.allocate(1 + 4 + size).put(code).put(sizeB).put(content).array(); - - try { - - Packet p = Packet.constructPacket(packetData); - - if (!(p instanceof PacketServer)) - throw new PacketException(p.getClass().getCanonicalName() + " is not a subclass of PacketServer"); - - if (p instanceof PacketD0ServerException) { - - try { - listener.onServerException(this, ((PacketD0ServerException)p).getExceptionString()); - } catch (Exception e) { - Log.severe("Exception while calling TCPClientListener.onServerException()", e); - } - } - - PacketServer ps = (PacketServer) p; - - boolean callbackExecuted = executeCallbacks(ps, callbacksAvoidListener); - - try { - if (!callbackExecuted) - listener.onPacketReceive(this, ps); - } catch (Exception e) { - Log.severe("Exception while calling TCPClientListener.onPacketReceive()", e); - } - - executeCallbacks(ps, callbacks); - - } catch (Exception e) { - Log.severe("Exception while handling packet from server", e); - } - } - - } catch (Exception e) { - Log.severe(e); - } - close(); - } - - - private boolean executeCallbacks(PacketServer ps, List, ResponseCallback>> callbacks) { - boolean executedOne = false; - synchronized (callbacks) { - for(Iterator, ResponseCallback>> it = callbacks.iterator(); it.hasNext();) { - Pair, ResponseCallback> c = it.next(); - try { - if (c.getValue0().test(ps)) { - it.remove(); - c.getValue1().call(ps); - executedOne = true; - } - } catch (Exception e) { - Log.severe("Exception while executing callback", e); - } - } - } - return executedOne; - } - - - private void forceReadBytes(byte[] buff) throws IOException { - int pos = 0; - do { - int nbR = in.read(buff, pos, buff.length - pos); - if (nbR == -1) throw new IOException("Can't read required amount of byte"); - pos += nbR; - } while (pos < buff.length); - } - - public void send(PacketClient packet) throws IOException { - synchronized (outSynchronizer) { - out.write(packet.getFullSerializedPacket()); - out.flush(); - } - } - - - public void sendAndGetResponse(PacketClient packet, Predicate responseCondition, ResponseCallback callback, boolean avoidListener) throws IOException { - Pair, ResponseCallback> p = new Pair<>(responseCondition, callback); - if (avoidListener) - callbacksAvoidListener.add(p); - else - callbacks.add(p); - send(packet); - } - - - public PacketServer sendAndWaitForResponse(PacketClient packet, Predicate responseCondition) throws IOException, InterruptedException { - AtomicReference psStorage = new AtomicReference<>(null); - synchronized (psStorage) { - sendAndGetResponse(packet, responseCondition, packetServer -> { - synchronized (psStorage) { - psStorage.set(packetServer); - psStorage.notifyAll(); - } - }, true); - - psStorage.wait(); - return psStorage.get(); - } - } - - - - @Override - public void close() { - try { - synchronized (outSynchronizer) { - if (isClosed.get()) return; - socket.close(); - isClosed.set(true); - - try { - listener.onDisconnect(this); - } catch (Exception e) { - Log.severe("Exception while calling TCPClientListener.onDisconnect()", e); - } - } - } catch (IOException e) { - Log.warning(e); - } - } - - public void sendSilently(PacketClient packet) { - try { - send(packet); - } catch (IOException e) {} - } - - public SocketAddress getServerAddress() { - return addr; - } - - public boolean isClosed() { - return isClosed.get() || socket.isClosed(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("thread", getName()) - .append("socket", socket.getRemoteSocketAddress()).toString(); - } - -} diff --git a/src/main/java/fr/pandacube/util/network/client/TCPClientListener.java b/src/main/java/fr/pandacube/util/network/client/TCPClientListener.java deleted file mode 100644 index 1a60b4d..0000000 --- a/src/main/java/fr/pandacube/util/network/client/TCPClientListener.java +++ /dev/null @@ -1,42 +0,0 @@ -package fr.pandacube.util.network.client; - -import fr.pandacube.util.Log; -import fr.pandacube.util.network.packet.PacketServer; - -public interface TCPClientListener { - - /** - * Called when a connection is opened - * @param connection the connection which is opening - */ - public void onConnect(TCPClient connection); - - /** - * Called when the server send us a PacketServerException when an exception is thrown - * server side when handling our packets or eventually when the client is concerned - * with this error.
    - * The default implementation of this method just call the internal Logger of PandacubeUtil - * to print the stacktrace of the Exception. - * @param connection the connection which just received the error - * @param exceptionString a string representation of the exception. If the server - * use this Java library, it may be a full representation of - * {@link Throwable#printStackTrace()}. - */ - public default void onServerException(TCPClient connection, String exceptionString) { - Log.severe("Exception thrown by server through " + connection + " : \n"+exceptionString); - } - - /** - * Called when the server send us a packet - * @param connection the connection where the packet come from - * @param packet the packet - */ - public void onPacketReceive(TCPClient connection, PacketServer packet); - - /** - * Called before the connection closed - * @param connection the connection which is closing - */ - public void onDisconnect(TCPClient connection); - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/Packet.java b/src/main/java/fr/pandacube/util/network/packet/Packet.java deleted file mode 100644 index d9b4d68..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/Packet.java +++ /dev/null @@ -1,118 +0,0 @@ -package fr.pandacube.util.network.packet; - -import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import fr.pandacube.Pandacube; -import fr.pandacube.util.Log; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; -import fr.pandacube.util.network.packet.bytebuffer.ByteSerializable; -import fr.pandacube.util.network.packet.packets.core_slave.Packet30ClientDeclareProcess; -import fr.pandacube.util.network.packet.packets.core_slave.Packet31ClientClose; -import fr.pandacube.util.network.packet.packets.core_slave.Packet32ClientProcessQueryResponse; -import fr.pandacube.util.network.packet.packets.core_slave.PacketB0ServerClose; -import fr.pandacube.util.network.packet.packets.core_slave.PacketB1ServerProcessDeclarationConfirm; -import fr.pandacube.util.network.packet.packets.core_slave.PacketB2ServerConnectSuccess; -import fr.pandacube.util.network.packet.packets.core_slave.PacketB3ServerProcessInput; -import fr.pandacube.util.network.packet.packets.core_slave.PacketB4ServerProcessQuery; -import fr.pandacube.util.network.packet.packets.global.Packet50ClientAuthenticate; -import fr.pandacube.util.network.packet.packets.global.Packet51ClientLogRecord; -import fr.pandacube.util.network.packet.packets.global.PacketD0ServerException; -import fr.pandacube.util.network.packet.packets.global.PacketD1ServerCantAuthenticate; -import fr.pandacube.util.network.packet.packets.web.Packet00ClientWebRequest; -import fr.pandacube.util.network.packet.packets.web.Packet80ServerWebResponse; - -/**
    - * Identification des packets réseaux
    - * byte      (xxxxxxxx)
    - *                      client :       server :
    - * clt / sv  (x-------) (0-------)     (1-------)
    - *                      0x00 - 0x7F    0x80 - 0xFF
    - * use case  (-xxx----)
    - * - web     (-000----) 0x00 - 0x0F    0x80 - 0x8F (client is Apache, server is PandacubeCore master (PandacubeWeb))
    - * - spigot  (-001----) 0x10 - 0x1F    0x90 - 0x9F (client is PandacubeSpigot, server is PandacubeCore master)
    - * - bungee  (-010----) 0x20 - 0x2F    0xA0 - 0xAF (client is PandacubeBungee, server is PandacubeCore master)
    - * -coreslave(-011----) 0x30 - 0x3F    0xB0 - 0xBF (client is PandacubeCore slave, sv is PandacubeCore master)
    - * - global  (-101----) 0x50 - 0x5F    0xD0 - 0xDF
    - * 
    - * - reserved if not enough packet id in certain use case
    - *           (-11x----) 0x60 - 0x7F    0xE0 - 0xFF
    - * 
    - * packet id (----xxxx)
    - * 
    - */ -public abstract class Packet implements ByteSerializable { - - private final byte code; - - public Packet(byte c) { - code = c; - } - - public byte getCode() { - return code; - } - - public byte[] getFullSerializedPacket() { - ByteBuffer internal = new ByteBuffer(CHARSET).putObject(this); - byte[] data = Arrays.copyOfRange(internal.array(), 0, internal.getPosition()); - - return new ByteBuffer(5 + data.length, CHARSET).putByte(code).putInt(data.length).putByteArray(data).array(); - } - - public static final Charset CHARSET = Pandacube.NETWORK_CHARSET; - - private static Map> packetTypes = new HashMap<>(); - - public static Packet constructPacket(byte[] data) { - if (!packetTypes.containsKey(data[0])) - throw new PacketException("Packet identifier not recognized: 0x" + String.format("%02X", data[0]) - + ". Maybe this packet is not registered with Packet.addPacket()"); - - try { - Packet p = packetTypes.get(data[0]).newInstance(); - ByteBuffer dataBuffer = new ByteBuffer(Arrays.copyOfRange(data, 5, data.length), CHARSET); - p.deserializeFromByteBuffer(dataBuffer); - return p; - } catch (Exception e) { - throw new PacketException("Error while constructing packet", e); - } - } - - private static void addPacket(Class packetClass) { - try { - Packet p = packetClass.newInstance(); - packetTypes.put(p.code, packetClass); - } catch (Exception e) { - Log.severe(e); - } - } - - - static { - - /* - * Ajout des types de packets (client + serveur) - */ - addPacket(Packet31ClientClose.class); - addPacket(Packet30ClientDeclareProcess.class); - addPacket(Packet32ClientProcessQueryResponse.class); - addPacket(PacketB0ServerClose.class); - addPacket(PacketB2ServerConnectSuccess.class); - addPacket(PacketB1ServerProcessDeclarationConfirm.class); - addPacket(PacketB3ServerProcessInput.class); - addPacket(PacketB4ServerProcessQuery.class); - - addPacket(Packet50ClientAuthenticate.class); - addPacket(Packet51ClientLogRecord.class); - addPacket(PacketD1ServerCantAuthenticate.class); - addPacket(PacketD0ServerException.class); - - addPacket(Packet00ClientWebRequest.class); - addPacket(Packet80ServerWebResponse.class); - - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/PacketClient.java b/src/main/java/fr/pandacube/util/network/packet/PacketClient.java deleted file mode 100644 index e79d9fd..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/PacketClient.java +++ /dev/null @@ -1,13 +0,0 @@ -package fr.pandacube.util.network.packet; - -/** - * On attend d'un instance de {@link PacketClient} qu'il soit envoyé depuis - * une connexion Client vers une connexion Serveur (d'un point de vue TCP) - */ -public abstract class PacketClient extends Packet { - - public PacketClient(byte c) { - super(c); - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/PacketException.java b/src/main/java/fr/pandacube/util/network/packet/PacketException.java deleted file mode 100644 index 2f27055..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/PacketException.java +++ /dev/null @@ -1,24 +0,0 @@ -package fr.pandacube.util.network.packet; - -/** - * - * Thrown when there is a problem when constructing, sending or handling a packet. - * - * Only the server may send a string representation of an exception to the client, not the reverse - * - */ -public class PacketException extends RuntimeException { - private static final long serialVersionUID = 1L; - - public PacketException(String m) { - super(m); - } - - public PacketException(String m, Throwable t) { - super(m, t); - } - - public PacketException(Throwable t) { - super(t); - } -} diff --git a/src/main/java/fr/pandacube/util/network/packet/PacketServer.java b/src/main/java/fr/pandacube/util/network/packet/PacketServer.java deleted file mode 100644 index 2299806..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/PacketServer.java +++ /dev/null @@ -1,13 +0,0 @@ -package fr.pandacube.util.network.packet; - -/** - * On attend d'un instance de {@link PacketServer} qu'il soit envoyé depuis - * une connexion Serveur vers une connexion Client (d'un point de vue TCP) - */ -public abstract class PacketServer extends Packet { - - public PacketServer(byte c) { - super(c); - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/ResponseCallback.java b/src/main/java/fr/pandacube/util/network/packet/ResponseCallback.java deleted file mode 100644 index f6ffbc9..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/ResponseCallback.java +++ /dev/null @@ -1,8 +0,0 @@ -package fr.pandacube.util.network.packet; - -@FunctionalInterface -public interface ResponseCallback { - - public void call(T packet); - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/bytebuffer/ByteSerializable.java b/src/main/java/fr/pandacube/util/network/packet/bytebuffer/ByteSerializable.java deleted file mode 100644 index f7035b9..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/bytebuffer/ByteSerializable.java +++ /dev/null @@ -1,19 +0,0 @@ -package fr.pandacube.util.network.packet.bytebuffer; - -/** - * Cette interface permet à un {@link ByteBuffer} de sérialiser sous forme de - * données binaire - * les attributs de la classe courante.
    - *
    - * Les classes concrètes implémentant cette interface doivent avoir un - * constructeur vide, utilisé - * lors de la désérialisation - * - */ -public interface ByteSerializable { - - public void serializeToByteBuffer(ByteBuffer buffer); - - public void deserializeFromByteBuffer(ByteBuffer buffer); - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/Packet30ClientDeclareProcess.java b/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/Packet30ClientDeclareProcess.java deleted file mode 100644 index 7cd826e..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/Packet30ClientDeclareProcess.java +++ /dev/null @@ -1,39 +0,0 @@ -package fr.pandacube.util.network.packet.packets.core_slave; - -import fr.pandacube.util.network.packet.PacketClient; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class Packet30ClientDeclareProcess extends PacketClient { - - private String processName; - private String type; - - public Packet30ClientDeclareProcess() { - super((byte)0x30); - } - - public void setProcessName(String pN) { - processName = pN; - } - - public void setType(String t) { - type = t; - } - - public String getProcessName() { return processName; } - public String getType() { return type; } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - buffer.putString(processName); - buffer.putString(type); - - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - processName = buffer.getString(); - type = buffer.getString(); - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/Packet31ClientClose.java b/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/Packet31ClientClose.java deleted file mode 100644 index 3c56745..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/Packet31ClientClose.java +++ /dev/null @@ -1,22 +0,0 @@ -package fr.pandacube.util.network.packet.packets.core_slave; - -import fr.pandacube.util.network.packet.PacketClient; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class Packet31ClientClose extends PacketClient { - - public Packet31ClientClose() { - super((byte)0x31); - } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - // no data - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - // no data - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/Packet32ClientProcessQueryResponse.java b/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/Packet32ClientProcessQueryResponse.java deleted file mode 100644 index 229229e..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/Packet32ClientProcessQueryResponse.java +++ /dev/null @@ -1,61 +0,0 @@ -package fr.pandacube.util.network.packet.packets.core_slave; - -import fr.pandacube.util.network.packet.PacketClient; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; -import fr.pandacube.util.network.packet.packets.core_slave.PacketB4ServerProcessQuery.QueryType; - -public class Packet32ClientProcessQueryResponse extends PacketClient { - - private QueryType type; - private int queryId; - private byte[] responseData = null; - - - public Packet32ClientProcessQueryResponse() { - super((byte)0x32); - } - - public QueryType getType() { return type; } - public int getQueryId() { return queryId; } - public byte[] getResponseData() { return responseData; } - - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - buffer.putInt(type.ordinal()); - buffer.putInt(queryId); - buffer.putSizedByteArray(responseData); - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - type = QueryType.values()[buffer.getInt()]; - queryId = buffer.getInt(); - responseData = buffer.getSizedByteArray(); - } - - - public static Packet32ClientProcessQueryResponse destroyResponse(int queryId) { - Packet32ClientProcessQueryResponse q = new Packet32ClientProcessQueryResponse(); - q.type = QueryType.DESTROY; - q.queryId = queryId; - return q; - } - - public static Packet32ClientProcessQueryResponse isAliveResponse(int queryId, boolean resp) { - Packet32ClientProcessQueryResponse q = new Packet32ClientProcessQueryResponse(); - q.type = QueryType.IS_ALIVE; - q.queryId = queryId; - q.responseData = new byte[] {(byte)(resp ? 1 : 0)}; - return q; - } - - public static Packet32ClientProcessQueryResponse exitStatusResponse(int queryId, int resp) { - Packet32ClientProcessQueryResponse q = new Packet32ClientProcessQueryResponse(); - q.type = QueryType.EXIT_STATUS; - q.queryId = queryId; - q.responseData = new ByteBuffer(4, CHARSET).putInt(resp).array(); - return q; - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB0ServerClose.java b/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB0ServerClose.java deleted file mode 100644 index 31169c3..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB0ServerClose.java +++ /dev/null @@ -1,22 +0,0 @@ -package fr.pandacube.util.network.packet.packets.core_slave; - -import fr.pandacube.util.network.packet.PacketServer; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class PacketB0ServerClose extends PacketServer { - - public PacketB0ServerClose() { - super((byte)0xB0); - } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - // no data - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - // no data - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB1ServerProcessDeclarationConfirm.java b/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB1ServerProcessDeclarationConfirm.java deleted file mode 100644 index de47a59..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB1ServerProcessDeclarationConfirm.java +++ /dev/null @@ -1,32 +0,0 @@ -package fr.pandacube.util.network.packet.packets.core_slave; - -import fr.pandacube.util.network.packet.PacketServer; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class PacketB1ServerProcessDeclarationConfirm extends PacketServer { - - private String serverName; - - public PacketB1ServerProcessDeclarationConfirm() { - super((byte)0xB1); - } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - buffer.putString(serverName); - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - serverName = buffer.getString(); - } - - public String getServerName() { - return serverName; - } - - public void setProcessName(String name) { - serverName = name; - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB2ServerConnectSuccess.java b/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB2ServerConnectSuccess.java deleted file mode 100644 index c5154d8..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB2ServerConnectSuccess.java +++ /dev/null @@ -1,22 +0,0 @@ -package fr.pandacube.util.network.packet.packets.core_slave; - -import fr.pandacube.util.network.packet.PacketServer; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class PacketB2ServerConnectSuccess extends PacketServer { - - public PacketB2ServerConnectSuccess() { - super((byte)0xB2); - } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - // no data - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - // no data - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB3ServerProcessInput.java b/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB3ServerProcessInput.java deleted file mode 100644 index e596318..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB3ServerProcessInput.java +++ /dev/null @@ -1,42 +0,0 @@ -package fr.pandacube.util.network.packet.packets.core_slave; - -import fr.pandacube.util.network.packet.PacketServer; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class PacketB3ServerProcessInput extends PacketServer { - - private String serverName; - private byte[] dataToSend; - - public PacketB3ServerProcessInput() { - super((byte)0xB3); - } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - buffer.putString(serverName); - buffer.putSizedByteArray(dataToSend); - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - serverName = buffer.getString(); - dataToSend = buffer.getSizedByteArray(); - } - - public String getServerName() { - return serverName; - } - - public void setServerName(String serverName) { - this.serverName = serverName; - } - - public byte[] getDataToSend() { - return dataToSend; - } - - public void setDataToSend(byte[] dataToSend) { - this.dataToSend = dataToSend; - } -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB4ServerProcessQuery.java b/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB4ServerProcessQuery.java deleted file mode 100644 index 1dc0e33..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/core_slave/PacketB4ServerProcessQuery.java +++ /dev/null @@ -1,73 +0,0 @@ -package fr.pandacube.util.network.packet.packets.core_slave; - -import fr.pandacube.util.RandomUtil; -import fr.pandacube.util.network.packet.PacketServer; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class PacketB4ServerProcessQuery extends PacketServer { - - private String processName; - private QueryType type; - private int queryId = RandomUtil.rand.nextInt(); - private byte[] queryData = null; - - - public PacketB4ServerProcessQuery() { - super((byte)0xB4); - } - - public String getProcessName() { return processName; } - public QueryType getType() { return type; } - public int getQueryId() { return queryId; } - public byte[] getQueryData() { return queryData; } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - buffer.putInt(type.ordinal()); - buffer.putInt(queryId); - buffer.putSizedByteArray(queryData); - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - type = QueryType.values()[buffer.getInt()]; - queryId = buffer.getInt(); - queryData = buffer.getSizedByteArray(); - } - - - public static PacketB4ServerProcessQuery startQuery(String processName) { - PacketB4ServerProcessQuery q = new PacketB4ServerProcessQuery(); - q.processName = processName; - q.type = QueryType.START; - return q; - } - - public static PacketB4ServerProcessQuery destroyQuery(String processName, boolean wait) { - PacketB4ServerProcessQuery q = new PacketB4ServerProcessQuery(); - q.processName = processName; - q.type = QueryType.DESTROY; - q.queryData = new byte[] {(byte)(wait ? 1 : 0)}; - return q; - } - - public static PacketB4ServerProcessQuery isAliveQuery(String processName) { - PacketB4ServerProcessQuery q = new PacketB4ServerProcessQuery(); - q.processName = processName; - q.type = QueryType.IS_ALIVE; - return q; - } - - public static PacketB4ServerProcessQuery exitStatusQuery(String processName) { - PacketB4ServerProcessQuery q = new PacketB4ServerProcessQuery(); - q.processName = processName; - q.type = QueryType.EXIT_STATUS; - return q; - } - - - public enum QueryType { - START, DESTROY, IS_ALIVE, EXIT_STATUS; - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/global/Packet50ClientAuthenticate.java b/src/main/java/fr/pandacube/util/network/packet/packets/global/Packet50ClientAuthenticate.java deleted file mode 100644 index 363692c..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/global/Packet50ClientAuthenticate.java +++ /dev/null @@ -1,35 +0,0 @@ -package fr.pandacube.util.network.packet.packets.global; - -import fr.pandacube.util.network.packet.PacketClient; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class Packet50ClientAuthenticate extends PacketClient { - - private String password; - private String additionalData = ""; - - public Packet50ClientAuthenticate() { - super((byte)0x50); - } - - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - buffer.putString(password); - buffer.putString(additionalData); - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - password = buffer.getString(); - additionalData = buffer.getString(); - } - - - public String getPassword() { return password; } - public void setPassword(String p) { password = p; } - - public String getAdditionalData() { return additionalData; } - public void setAdditionalData(String data) { additionalData = data; } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/global/Packet51ClientLogRecord.java b/src/main/java/fr/pandacube/util/network/packet/packets/global/Packet51ClientLogRecord.java deleted file mode 100644 index 4a4ec63..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/global/Packet51ClientLogRecord.java +++ /dev/null @@ -1,76 +0,0 @@ -package fr.pandacube.util.network.packet.packets.global; - -import fr.pandacube.util.network.packet.PacketClient; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class Packet51ClientLogRecord extends PacketClient { - - private long time; - private String level; - private String threadName; - private String message; - private String throwable; - - public Packet51ClientLogRecord() { - super((byte)0x51); - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - time = buffer.getLong(); - level = buffer.getString(); - threadName = buffer.getString(); - message = buffer.getString(); - throwable = buffer.getString(); - } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - buffer.putLong(time); - buffer.putString(level); - buffer.putString(threadName); - buffer.putString(message); - buffer.putString(throwable); - } - - public long getTime() { - return time; - } - - public void setTime(long time) { - this.time = time; - } - - public String getLevel() { - return level; - } - - public void setLevel(String level) { - this.level = level; - } - - public String getThreadName() { - return threadName; - } - - public void setThreadName(String threadName) { - this.threadName = threadName; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public String getThrowable() { - return throwable; - } - - public void setThrowable(String throwable) { - this.throwable = throwable; - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/global/PacketD0ServerException.java b/src/main/java/fr/pandacube/util/network/packet/packets/global/PacketD0ServerException.java deleted file mode 100644 index 55a4cbb..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/global/PacketD0ServerException.java +++ /dev/null @@ -1,38 +0,0 @@ -package fr.pandacube.util.network.packet.packets.global; - -import java.io.PrintWriter; -import java.io.StringWriter; - -import fr.pandacube.util.network.packet.PacketServer; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class PacketD0ServerException extends PacketServer { - - private String exception; - - public PacketD0ServerException() { - super((byte)0xD0); - } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - buffer.putString(exception); - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - exception = buffer.getString(); - } - - - public void setException(Throwable t) { - StringWriter sw = new StringWriter(); - t.printStackTrace(new PrintWriter(sw)); - exception = sw.toString(); - } - - public String getExceptionString() { - return exception; - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/global/PacketD1ServerCantAuthenticate.java b/src/main/java/fr/pandacube/util/network/packet/packets/global/PacketD1ServerCantAuthenticate.java deleted file mode 100644 index 035ed4e..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/global/PacketD1ServerCantAuthenticate.java +++ /dev/null @@ -1,20 +0,0 @@ -package fr.pandacube.util.network.packet.packets.global; - -import fr.pandacube.util.network.packet.PacketServer; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class PacketD1ServerCantAuthenticate extends PacketServer { - - public PacketD1ServerCantAuthenticate() { - super((byte)0xD1); - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/global/PacketD2ServerCommand.java b/src/main/java/fr/pandacube/util/network/packet/packets/global/PacketD2ServerCommand.java deleted file mode 100644 index 233c326..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/global/PacketD2ServerCommand.java +++ /dev/null @@ -1,30 +0,0 @@ -package fr.pandacube.util.network.packet.packets.global; - -import fr.pandacube.util.network.packet.PacketServer; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class PacketD2ServerCommand extends PacketServer { - - private String command; - private boolean async; - private boolean returnResult; - - public PacketD2ServerCommand() { - super((byte)0xD2); - } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - buffer.putString(command); - buffer.putByte((byte) (async ? 1 : 0)); - buffer.putByte((byte) (returnResult ? 1 : 0)); - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - command = buffer.getString(); - async = buffer.getByte() != 0; - returnResult = buffer.getByte() != 0; - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/web/Packet00ClientWebRequest.java b/src/main/java/fr/pandacube/util/network/packet/packets/web/Packet00ClientWebRequest.java deleted file mode 100644 index 56c7d04..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/web/Packet00ClientWebRequest.java +++ /dev/null @@ -1,43 +0,0 @@ -package fr.pandacube.util.network.packet.packets.web; - -import fr.pandacube.util.network.packet.PacketClient; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class Packet00ClientWebRequest extends PacketClient { - - private String password; - private String jsonData; - - public Packet00ClientWebRequest() { - super((byte)0x00); - } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - buffer.putString(password); - buffer.putString(jsonData); - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - password = buffer.getString(); - jsonData = buffer.getString(); - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getJsonData() { - return jsonData; - } - - public void setJsonData(String jsonData) { - this.jsonData = jsonData; - } - -} diff --git a/src/main/java/fr/pandacube/util/network/packet/packets/web/Packet80ServerWebResponse.java b/src/main/java/fr/pandacube/util/network/packet/packets/web/Packet80ServerWebResponse.java deleted file mode 100644 index 01f1d88..0000000 --- a/src/main/java/fr/pandacube/util/network/packet/packets/web/Packet80ServerWebResponse.java +++ /dev/null @@ -1,32 +0,0 @@ -package fr.pandacube.util.network.packet.packets.web; - -import fr.pandacube.util.network.packet.PacketServer; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; - -public class Packet80ServerWebResponse extends PacketServer { - - private String jsonData; - - public Packet80ServerWebResponse() { - super((byte)0x80); - } - - @Override - public void serializeToByteBuffer(ByteBuffer buffer) { - buffer.putString(jsonData); - } - - @Override - public void deserializeFromByteBuffer(ByteBuffer buffer) { - jsonData = buffer.getString(); - } - - public String getJsonData() { - return jsonData; - } - - public void setJsonData(String jsonData) { - this.jsonData = jsonData; - } - -} diff --git a/src/main/java/fr/pandacube/util/network/server/BandwidthCalculation.java b/src/main/java/fr/pandacube/util/network/server/BandwidthCalculation.java deleted file mode 100644 index 2327c7a..0000000 --- a/src/main/java/fr/pandacube/util/network/server/BandwidthCalculation.java +++ /dev/null @@ -1,56 +0,0 @@ -package fr.pandacube.util.network.server; - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import fr.pandacube.util.network.server.TCPServer.TCPServerClientConnection; - -public class BandwidthCalculation { - - private List packetHistory = new LinkedList<>(); - - public synchronized void addPacket(TCPServerClientConnection co, boolean in, long size) { - packetHistory.add(new PacketStat(co, in, size)); - } - - /** - * Get the instant bandwith in byte/s - * - * @param input true if getting input bw, false if getting output, null if - * getting input + output - * @param co - * @return - */ - public synchronized long getBandWidth(Boolean input, TCPServerClientConnection co) { - long currentTime = System.currentTimeMillis(); - Iterator it = packetHistory.iterator(); - long sum = 0; - while (it.hasNext()) { - PacketStat el = it.next(); - if (el.time < currentTime - 1000) { - it.remove(); - continue; - } - if (input != null && el.input != input.booleanValue()) continue; - if (co != null && !co.equals(el.connection)) continue; - sum += el.packetSize; - } - return sum; - } - - private class PacketStat { - public final long time; - public final long packetSize; - public final boolean input; - public final TCPServerClientConnection connection; - - public PacketStat(TCPServerClientConnection co, boolean input, long size) { - time = System.currentTimeMillis(); - packetSize = size; - this.input = input; - connection = co; - } - } - -} diff --git a/src/main/java/fr/pandacube/util/network/server/TCPServer.java b/src/main/java/fr/pandacube/util/network/server/TCPServer.java deleted file mode 100644 index a5c9210..0000000 --- a/src/main/java/fr/pandacube/util/network/server/TCPServer.java +++ /dev/null @@ -1,355 +0,0 @@ -package fr.pandacube.util.network.server; - -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketAddress; -import java.net.SocketException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Predicate; -import java.util.logging.Level; - -import org.apache.commons.lang.builder.ToStringBuilder; -import org.javatuples.Pair; - -import fr.pandacube.Pandacube; -import fr.pandacube.util.Log; -import fr.pandacube.util.network.packet.Packet; -import fr.pandacube.util.network.packet.PacketClient; -import fr.pandacube.util.network.packet.PacketException; -import fr.pandacube.util.network.packet.PacketServer; -import fr.pandacube.util.network.packet.ResponseCallback; -import fr.pandacube.util.network.packet.bytebuffer.ByteBuffer; -import fr.pandacube.util.network.packet.packets.global.PacketD0ServerException; - -/** - * - * @author Marc Baloup - * - */ -public class TCPServer extends Thread implements Closeable { - private static AtomicInteger connectionCounterId = new AtomicInteger(0); - - private ServerSocket socket; - private TCPServerListener listener; - private String socketName; - - private List clients = Collections.synchronizedList(new ArrayList<>()); - - private AtomicBoolean isClosed = new AtomicBoolean(false); - - public final BandwidthCalculation bandwidthCalculation = new BandwidthCalculation(); - - public TCPServer(int port, String sckName, TCPServerListener l) throws IOException { - super("TCPSv " + sckName); - setDaemon(true); - if (port <= 0 || port > 65535) throw new IllegalArgumentException("le numéro de port est invalide"); - socket = new ServerSocket(); - socket.setReceiveBufferSize(Pandacube.NETWORK_TCP_BUFFER_SIZE); - socket.setPerformancePreferences(0, 1, 0); - socket.bind(new InetSocketAddress(port)); - listener = l; - try { - listener.onSocketOpen(this); - } catch(Exception e) { - Log.severe("Exception while calling TCPServerListener.onSocketOpen()", e); - } - socketName = sckName; - } - - @Override - public void run() { - - try { - while (true) { - Socket socketClient = socket.accept(); - socketClient.setSendBufferSize(Pandacube.NETWORK_TCP_BUFFER_SIZE); - socketClient.setSoTimeout(Pandacube.NETWORK_TIMEOUT); - - try { - TCPServerClientConnection co = new TCPServerClientConnection(socketClient, - connectionCounterId.getAndIncrement()); - clients.add(co); - co.start(); - } catch (IOException e) { - Log.getLogger().log(Level.SEVERE, "Connexion impossible avec " + socketClient.getInetAddress()); - } - } - } catch(SocketException e) { - - } catch (Exception e) { - Log.warning("Plus aucune connexion ne peux être acceptée", e); - } - } - - public class TCPServerClientConnection extends Thread { - private Socket cSocket; - private InputStream in; - private OutputStream out; - private SocketAddress address; - private TCPServerConnectionOutputThread outThread; - private List, ResponseCallback>> callbacks = Collections.synchronizedList(new ArrayList<>()); - private List, ResponseCallback>> callbacksAvoidListener = Collections.synchronizedList(new ArrayList<>()); - - - public TCPServerClientConnection(Socket s, int coId) throws IOException { - super("TCPSv " + socketName + " Conn#" + coId + " In"); - setDaemon(true); - cSocket = s; - in = cSocket.getInputStream(); - out = cSocket.getOutputStream(); - address = new InetSocketAddress(cSocket.getInetAddress(), cSocket.getPort()); - try { - listener.onClientConnect(TCPServer.this, this); - } catch(Exception e) { - Log.severe("Exception while calling TCPServerListener.onClientConnect()", e); - } - outThread = new TCPServerConnectionOutputThread(coId); - outThread.start(); - } - - @Override - public void run() { - try { - byte[] code = new byte[1]; - while (!cSocket.isClosed() && in.read(code) != -1) { - byte[] sizeB = new byte[4]; - if (in.read(sizeB) != 4) throw new IOException("Socket " + address + " closed"); - - int size = new ByteBuffer(sizeB, Packet.CHARSET).getInt(); - - byte[] content = new byte[size]; - - forceReadBytes(content); - - byte[] packetData = new ByteBuffer(1 + 4 + size, Packet.CHARSET).putByteArray(code).putByteArray(sizeB) - .putByteArray(content).array(); - - bandwidthCalculation.addPacket(this, true, packetData.length); - - try { - Packet p = Packet.constructPacket(packetData); - - if (!(p instanceof PacketClient)) - throw new PacketException(p.getClass().getCanonicalName() + " is not an instanceof PacketClient"); - - PacketClient pc = (PacketClient) p; - - boolean oneCallbackExecuted = executeCallbacks(pc, callbacksAvoidListener); - - if (!oneCallbackExecuted) - listener.onPacketReceive(TCPServer.this, this, pc); - - executeCallbacks(pc, callbacks); - - } catch (Throwable e) { - Log.severe("Exception while handling packet. This exception will be sent to the client with PacketServerException packet.", e); - PacketD0ServerException packet = new PacketD0ServerException(); - packet.setException(e); - send(packet); - if (e instanceof InterruptedException || e instanceof Error) - throw e; - } - } - - } catch(SocketException e) { - } catch (Exception e) { - Log.severe("Closing connection " + address, e); - } - - close(); - } - - - private boolean executeCallbacks(PacketClient pc, List, ResponseCallback>> callbacks) { - boolean executedOne = false; - synchronized (callbacks) { - for(Iterator, ResponseCallback>> it = callbacks.iterator(); it.hasNext();) { - Pair, ResponseCallback> c = it.next(); - try { - if (c.getValue0().test(pc)) { - it.remove(); - c.getValue1().call(pc); - executedOne = true; - } - } catch (Exception e) { - Log.severe("Exception while executing callback", e); - } - } - } - return executedOne; - } - - public void send(PacketServer p) { - outThread.addPacket(p); - } - - public void sendAndGetResponse(PacketServer packet, Predicate responseCondition, ResponseCallback callback, boolean avoidListener) { - Pair, ResponseCallback> p = new Pair<>(responseCondition, callback); - if (avoidListener) - callbacksAvoidListener.add(p); - else - callbacks.add(p); - send(packet); - } - - - - /** - * - * @param packet the packet to send - * @param responseCondition {@link Predicate} that check each received packet to know which - * is the expected one as a response of the sended packet. - * @param avoidListener - * @param timeout - * @return - * @throws InterruptedException - */ - public PacketClient sendAndWaitForResponse(PacketServer packet, Predicate responseCondition, boolean avoidListener, long timeout) throws InterruptedException { - AtomicReference pcStorage = new AtomicReference<>(null); - synchronized (pcStorage) { - sendAndGetResponse(packet, responseCondition, packetClient -> { - synchronized (pcStorage) { - pcStorage.set(packetClient); - pcStorage.notifyAll(); - } - }, true); - - pcStorage.wait(timeout); - return pcStorage.get(); - } - } - - private void forceReadBytes(byte[] buff) throws IOException { - int pos = 0; - do { - int nbR = in.read(buff, pos, buff.length - pos); - if (nbR == -1) throw new IOException("Can't read required amount of byte"); - pos += nbR; - } while (pos < buff.length); - } - - public void close() { - if (cSocket.isClosed()) return; - - try { - listener.onClientDisconnect(TCPServer.this, this); - } catch(Exception e) { - Log.severe("Exception while calling TCPServerListener.onClientDisconnect()", e); - } - clients.remove(this); - - try { - Thread.sleep(200); - cSocket.close(); - if (!Thread.currentThread().equals(outThread)) send(new PacketServer((byte) 0) { - @Override public void serializeToByteBuffer(ByteBuffer buffer) {} - @Override public void deserializeFromByteBuffer(ByteBuffer buffer) {} - }); - // provoque une exception dans le thread de sortie, et la - // termine - } catch (Exception e) { } - } - - private class TCPServerConnectionOutputThread extends Thread { - private BlockingQueue packetQueue = new LinkedBlockingDeque<>(); - - public TCPServerConnectionOutputThread(int coId) { - super("TCPSv " + socketName + " Conn#" + coId + " Out"); - setDaemon(true); - } - - private void addPacket(PacketServer packet) { - packetQueue.add(packet); - } - - @Override - public void run() { - try { - while (!cSocket.isClosed()) { - PacketServer packet = packetQueue.poll(1, TimeUnit.SECONDS); - byte[] data; - if (packet != null) { - try { - data = packet.getFullSerializedPacket(); - bandwidthCalculation.addPacket(TCPServerClientConnection.this, false, data.length); - out.write(data); - out.flush(); - } catch (IOException e) { - throw e; - } catch (Exception e) { - Log.severe("Can't send packet "+packet.getClass(), e); - } - } - - } - } catch (InterruptedException|IOException e) {} - - close(); - } - - } - - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("thread", getName()) - .append("socket", cSocket).toString(); - } - - } - - @Override - public void close() { - try { - if (isClosed.get()) return; - isClosed.set(true); - - clients.forEach(el -> el.close()); - - try { - listener.onSocketClose(this); - } catch(Exception e) { - Log.severe("Exception while calling TCPServerListener.onSocketClose()", e); - } - - socket.close(); - } catch (IOException e) {} - } - - public boolean isClosed() { - return isClosed.get() || socket.isClosed(); - } - - - - public List getClients() { - synchronized (clients) { - return new ArrayList<>(clients); - } - } - - - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("thread", getName()) - .append("socket", socket).toString(); - } - -} diff --git a/src/main/java/fr/pandacube/util/network/server/TCPServerListener.java b/src/main/java/fr/pandacube/util/network/server/TCPServerListener.java deleted file mode 100644 index a987c64..0000000 --- a/src/main/java/fr/pandacube/util/network/server/TCPServerListener.java +++ /dev/null @@ -1,19 +0,0 @@ -package fr.pandacube.util.network.server; - -import fr.pandacube.util.network.packet.PacketClient; -import fr.pandacube.util.network.server.TCPServer.TCPServerClientConnection; - -public interface TCPServerListener { - - public void onSocketOpen(TCPServer svConnection); - - public void onClientConnect(TCPServer svConnection, TCPServerClientConnection clientConnection); - - public void onPacketReceive(TCPServer svConnection, TCPServerClientConnection clientConnection, - PacketClient packet); - - public void onClientDisconnect(TCPServer svConnection, TCPServerClientConnection clientConnection); - - public void onSocketClose(TCPServer svConnection); - -} diff --git a/src/main/java/fr/pandacube/util/network_api/client/AbstractRequest.java b/src/main/java/fr/pandacube/util/network_api/client/AbstractRequest.java index 3168d06..e4aed64 100644 --- a/src/main/java/fr/pandacube/util/network_api/client/AbstractRequest.java +++ b/src/main/java/fr/pandacube/util/network_api/client/AbstractRequest.java @@ -2,6 +2,7 @@ package fr.pandacube.util.network_api.client; import java.io.PrintStream; +@Deprecated public abstract class AbstractRequest { private final String pass; diff --git a/src/main/java/fr/pandacube/util/network_api/client/NetworkAPISender.java b/src/main/java/fr/pandacube/util/network_api/client/NetworkAPISender.java index 1b1db64..d32dc3a 100644 --- a/src/main/java/fr/pandacube/util/network_api/client/NetworkAPISender.java +++ b/src/main/java/fr/pandacube/util/network_api/client/NetworkAPISender.java @@ -5,6 +5,7 @@ import java.io.PrintStream; import java.net.InetSocketAddress; import java.net.Socket; +@Deprecated public class NetworkAPISender { public static ResponseAnalyser sendRequest(InetSocketAddress cible, AbstractRequest request) throws IOException { diff --git a/src/main/java/fr/pandacube/util/network_api/client/ResponseAnalyser.java b/src/main/java/fr/pandacube/util/network_api/client/ResponseAnalyser.java index 2487687..29c5a74 100644 --- a/src/main/java/fr/pandacube/util/network_api/client/ResponseAnalyser.java +++ b/src/main/java/fr/pandacube/util/network_api/client/ResponseAnalyser.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; +@Deprecated public class ResponseAnalyser { /** * Indique si la requête s'est bien exécutée (l'entête de la réponse est diff --git a/src/main/java/fr/pandacube/util/network_api/server/AbstractRequestExecutor.java b/src/main/java/fr/pandacube/util/network_api/server/AbstractRequestExecutor.java index 7dee114..cd8d350 100644 --- a/src/main/java/fr/pandacube/util/network_api/server/AbstractRequestExecutor.java +++ b/src/main/java/fr/pandacube/util/network_api/server/AbstractRequestExecutor.java @@ -7,6 +7,7 @@ import java.net.Socket; import fr.pandacube.util.Log; +@Deprecated public abstract class AbstractRequestExecutor { public final String command; diff --git a/src/main/java/fr/pandacube/util/network_api/server/NAPIExecutionHandler.java b/src/main/java/fr/pandacube/util/network_api/server/NAPIExecutionHandler.java deleted file mode 100644 index 7e7aa87..0000000 --- a/src/main/java/fr/pandacube/util/network_api/server/NAPIExecutionHandler.java +++ /dev/null @@ -1,14 +0,0 @@ -package fr.pandacube.util.network_api.server; - -/** - * Interface permettant de gérer l'exécution asynchrone d'un PacketExecutor. - * - * @author Marc Baloup - * - */ -@FunctionalInterface -public interface NAPIExecutionHandler { - - public void handleRun(Runnable executor); - -} diff --git a/src/main/java/fr/pandacube/util/network_api/server/NetworkAPIListener.java b/src/main/java/fr/pandacube/util/network_api/server/NetworkAPIListener.java index 5df807c..ae9e53c 100644 --- a/src/main/java/fr/pandacube/util/network_api/server/NetworkAPIListener.java +++ b/src/main/java/fr/pandacube/util/network_api/server/NetworkAPIListener.java @@ -5,6 +5,7 @@ import java.net.ServerSocket; import java.util.Arrays; import java.util.HashMap; +@Deprecated public class NetworkAPIListener implements Runnable { private int port = 0; @@ -12,7 +13,6 @@ public class NetworkAPIListener implements Runnable { private ServerSocket serverSocket; private HashMap requestExecutors = new HashMap<>(); private String name; - private NAPIExecutionHandler nAPIExecutionHandler; /** * Instencie le côté serveur du NetworkAPI @@ -23,11 +23,10 @@ public class NetworkAPIListener implements Runnable { * @param peh PacketExecutionHandler permettant de prendre en charge * l'exécution asynchrone d'une requête reçu pas un client */ - public NetworkAPIListener(String n, int p, String pa, NAPIExecutionHandler peh) { + public NetworkAPIListener(String n, int p, String pa) { port = p; pass = pa; name = n; - nAPIExecutionHandler = peh; } @Override @@ -46,7 +45,9 @@ public class NetworkAPIListener implements Runnable { try { // réception des connexion client while (!serverSocket.isClosed()) { - nAPIExecutionHandler.handleRun(new PacketExecutor(serverSocket.accept(), this)); + Thread t = new Thread(new PacketExecutor(serverSocket.accept(), this)); + t.setDaemon(true); + t.start(); } } catch (IOException e) {} diff --git a/src/main/java/fr/pandacube/util/network_api/server/PacketExecutor.java b/src/main/java/fr/pandacube/util/network_api/server/PacketExecutor.java index 62ebcc0..1d1fb81 100644 --- a/src/main/java/fr/pandacube/util/network_api/server/PacketExecutor.java +++ b/src/main/java/fr/pandacube/util/network_api/server/PacketExecutor.java @@ -16,6 +16,7 @@ import fr.pandacube.util.network_api.server.RequestAnalyser.BadRequestException; * @author Marc Baloup * */ +@Deprecated public class PacketExecutor implements Runnable { private Socket socket; private NetworkAPIListener networkAPIListener; diff --git a/src/main/java/fr/pandacube/util/network_api/server/RequestAnalyser.java b/src/main/java/fr/pandacube/util/network_api/server/RequestAnalyser.java index 8fc6e9d..591bca5 100644 --- a/src/main/java/fr/pandacube/util/network_api/server/RequestAnalyser.java +++ b/src/main/java/fr/pandacube/util/network_api/server/RequestAnalyser.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; +@Deprecated public class RequestAnalyser { private NetworkAPIListener networkAPIListener; diff --git a/src/main/java/fr/pandacube/util/network_api/server/Response.java b/src/main/java/fr/pandacube/util/network_api/server/Response.java index f680d94..0304980 100644 --- a/src/main/java/fr/pandacube/util/network_api/server/Response.java +++ b/src/main/java/fr/pandacube/util/network_api/server/Response.java @@ -2,6 +2,7 @@ package fr.pandacube.util.network_api.server; import java.io.PrintStream; +@Deprecated public class Response { public boolean good = true; public String data = ""; diff --git a/src/main/java/fr/pandacube/util/network_api/server/ThreadNAPIExecutionHandler.java b/src/main/java/fr/pandacube/util/network_api/server/ThreadNAPIExecutionHandler.java deleted file mode 100644 index d0f9459..0000000 --- a/src/main/java/fr/pandacube/util/network_api/server/ThreadNAPIExecutionHandler.java +++ /dev/null @@ -1,12 +0,0 @@ -package fr.pandacube.util.network_api.server; - -public class ThreadNAPIExecutionHandler implements NAPIExecutionHandler { - - @Override - public void handleRun(Runnable executor) { - Thread t = new Thread(executor); - t.setDaemon(true); - t.start(); - } - -}