diff --git a/Extasys for Java Examples/Extasys.Examples.TCPChatClient/nbproject/private/private.xml b/Extasys for Java Examples/Extasys.Examples.TCPChatClient/nbproject/private/private.xml index 6807a2b..b0f76e5 100644 --- a/Extasys for Java Examples/Extasys.Examples.TCPChatClient/nbproject/private/private.xml +++ b/Extasys for Java Examples/Extasys.Examples.TCPChatClient/nbproject/private/private.xml @@ -2,6 +2,8 @@ - + + file:/C:/Development/extasys/Extasys%20for%20Java%20Examples/Extasys.Examples.TCPChatClient/src/Extasys/Examples/TCPChatClient/TCPChatClient.java + diff --git a/Extasys for Java Examples/Extasys.Examples.TCPChatClient/src/Extasys/Examples/TCPChatClient/TCPChatClient.java b/Extasys for Java Examples/Extasys.Examples.TCPChatClient/src/Extasys/Examples/TCPChatClient/TCPChatClient.java index ccbd93f..fd90461 100644 --- a/Extasys for Java Examples/Extasys.Examples.TCPChatClient/src/Extasys/Examples/TCPChatClient/TCPChatClient.java +++ b/Extasys for Java Examples/Extasys.Examples.TCPChatClient/src/Extasys/Examples/TCPChatClient/TCPChatClient.java @@ -20,6 +20,7 @@ of this software and associated documentation files (the "Software"), to deal package Extasys.Examples.TCPChatClient; import Extasys.DataFrame; +import Extasys.Encryption.Base64Encryptor; import Extasys.Network.TCP.Client.Connectors.TCPConnector; import Extasys.Network.TCP.Client.Exceptions.*; import java.net.InetAddress; @@ -36,17 +37,18 @@ public class TCPChatClient extends Extasys.Network.TCP.Client.ExtasysTCPClient private final String fUsername; private final frmTCPChatClient fMainForm; private String fSPT = String.valueOf(((char) 2)); // Message splitter character. - private String fMCChar = String.valueOf(((char) 3)); // Message collector character. public TCPChatClient(InetAddress serverIP, int port, String username, frmTCPChatClient frmMain) { - super("TCP Chat Client", "", 4, 8); + super("TCP Chat Client", "", 1, 2); fServerIP = serverIP; fPort = port; fUsername = username; fMainForm = frmMain; - super.AddConnector("Main Connector", serverIP, port, 20480, ((char) 3)); + TCPConnector connector = super.AddConnector("Main Connector", serverIP, port, 8192, ((char) 3)); + connector.setAutoApplyMessageSplitterState(true); // Auto apply message splitter to outgoing messages + connector.setConnectionEncryptor(new Base64Encryptor()); // Base 64 Encryption } public void Connect() @@ -66,69 +68,67 @@ public void OnDataReceive(TCPConnector connector, DataFrame data) { String[] splittedMessage = new String(data.getBytes()).split(fSPT); - if (splittedMessage[0].equals("Change_Username")) + switch (splittedMessage[0]) { - /* Message: Change_Username ((char)2) - This user must change username because this one is allready in use by an other user, - */ - fMainForm.MarkAsDisconnected(); - fMainForm.DisplayMessage("Please change your username. This one is allready in use by an other user."); - } - else if (splittedMessage[0].equals("Welcome")) - { - /* Message: Welcome ((char)2) - Server welcomes you. - */ - fMainForm.MarkAsConnected(); - fMainForm.DisplayMessage("You are now connected !!!"); - SendDataToServer("Get_List" + fSPT); - } - else if (splittedMessage[0].equals("User_List")) - { - /* Message: User_List ((char)2) list... - Server sends a list with connected clients to the client. - */ - if (!splittedMessage[1].equals("")) - { - String[] connectedUsers = splittedMessage[1].split(String.valueOf(((char) 1))); - for (int i = 0; i < connectedUsers.length; i++) + case "Change_Username": + // Message: Change_Username ((char)2) + // This user must change username because this one is allready in use by an other user. + fMainForm.MarkAsDisconnected(); + fMainForm.DisplayMessage("Please change your username. This one is allready in use by an other user."); + break; + + case "Welcome": + /* Message: Welcome ((char)2) + Server welcomes you. + */ + fMainForm.MarkAsConnected(); + fMainForm.DisplayMessage("You are now connected !!!"); + SendDataToServer("Get_List" + fSPT); + break; + + case "User_List": + // Message: User_List ((char)2) list... + // Server sends a list with connected clients to the client. + if (!splittedMessage[1].equals("")) { - if (!connectedUsers[i].equals(fUsername)) + String[] connectedUsers = splittedMessage[1].split(String.valueOf(((char) 1))); + for (int i = 0; i < connectedUsers.length; i++) { - fMainForm.AddUserInList(connectedUsers[i]); + if (!connectedUsers[i].equals(fUsername)) + { + fMainForm.AddUserInList(connectedUsers[i]); + } } } - } - } - else if (splittedMessage[0].equals("New_User")) - { - /* Message: New_User ((char)2) username - A new user connected to server. - */ - fMainForm.AddUserInList(splittedMessage[1]); - fMainForm.DisplayMessage("User " + splittedMessage[1] + " connected"); - } - else if (splittedMessage[0].equals("Remove_User")) - { - /* Message: Remove_User ((char)2) username - User disconnected from server. - */ - fMainForm.RemoveUser(splittedMessage[1]); - fMainForm.DisplayMessage("User " + splittedMessage[1] + " disconnected"); - } - else if (splittedMessage[0].equals("Message")) - { - /* Message: Message ((char)2) some_text - Server sends a message - */ - fMainForm.DisplayMessage(splittedMessage[1]); - } - else if (splittedMessage[0].equals("Ping")) - { - /* Message: Ping ((char)2) - Server pings you. - */ - SendDataToServer("Pong" + fSPT); + break; + + case "New_User": + // Message: New_User ((char)2) username + // A user connected to the server. + fMainForm.AddUserInList(splittedMessage[1]); + fMainForm.DisplayMessage("User " + splittedMessage[1] + " connected"); + break; + + case "Remove_User": + // Message: Remove_User ((char)2) username + // A user has been disconnected from server. + fMainForm.RemoveUser(splittedMessage[1]); + fMainForm.DisplayMessage("User " + splittedMessage[1] + " disconnected"); + break; + + case "Message": + // Message: Message ((char)2) some_text + // Server sends a message + fMainForm.DisplayMessage(splittedMessage[1]); + break; + + case "Ping": + // Message: Ping ((char)2) + // Server pings you. + SendDataToServer("Pong" + fSPT); + break; + default: + break; } } @@ -149,7 +149,7 @@ public void SendDataToServer(String data) { try { - super.SendData(data + fMCChar); + super.SendData(data); } catch (ConnectorDisconnectedException ex) { diff --git a/Extasys for Java Examples/Extasys.Examples.TCPChatServer/nbproject/private/private.xml b/Extasys for Java Examples/Extasys.Examples.TCPChatServer/nbproject/private/private.xml index 4750962..2c6a61a 100644 --- a/Extasys for Java Examples/Extasys.Examples.TCPChatServer/nbproject/private/private.xml +++ b/Extasys for Java Examples/Extasys.Examples.TCPChatServer/nbproject/private/private.xml @@ -1,4 +1,9 @@ + + + file:/C:/Development/extasys/Extasys%20for%20Java%20Examples/Extasys.Examples.TCPChatServer/src/Extasys/Examples/TCPChatServer/TCPChatServer.java + + diff --git a/Extasys for Java Examples/Extasys.Examples.TCPChatServer/src/Extasys/Examples/TCPChatServer/TCPChatServer.java b/Extasys for Java Examples/Extasys.Examples.TCPChatServer/src/Extasys/Examples/TCPChatServer/TCPChatServer.java index 6e3c4e0..17a2b09 100644 --- a/Extasys for Java Examples/Extasys.Examples.TCPChatServer/src/Extasys/Examples/TCPChatServer/TCPChatServer.java +++ b/Extasys for Java Examples/Extasys.Examples.TCPChatServer/src/Extasys/Examples/TCPChatServer/TCPChatServer.java @@ -20,9 +20,11 @@ of this software and associated documentation files (the "Software"), to deal package Extasys.Examples.TCPChatServer; import Extasys.DataFrame; -import Extasys.Network.TCP.Server.Listener.Exceptions.*; - +import Extasys.Encryption.Base64Encryptor; +import Extasys.Network.TCP.Server.Listener.Exceptions.ClientIsDisconnectedException; +import Extasys.Network.TCP.Server.Listener.Exceptions.OutgoingPacketFailedException; import Extasys.Network.TCP.Server.Listener.TCPClientConnection; +import Extasys.Network.TCP.Server.Listener.TCPListener; import java.net.InetAddress; import java.util.HashMap; @@ -34,16 +36,21 @@ public class TCPChatServer extends Extasys.Network.TCP.Server.ExtasysTCPServer { private final HashMap fConnectedClients; - private final String fSPT = String.valueOf(((char) 2)); // Message splitter character. - private final String fMCChar = String.valueOf(((char) 3)); // Message collector character. + + private final String fSPT = String.valueOf(((char) 2)); // Message splitter character. This is not the same as the message collector character + private Thread fPingThread; private boolean fServerIsActive; private final frmTCPChatServer fMainForm; public TCPChatServer(InetAddress listenerIP, int port, frmTCPChatServer frmMain) { - super("TCP Chat Server", "", 10, 100); - super.AddListener("Main Listener", listenerIP, port, 99999, 20480, 10000, 100, ((char) 3)); + super("TCP Chat Server", "This is a simple chat server", 10, 20); + + TCPListener listener = super.AddListener("Main Listener", listenerIP, port, 9999, 8192, 10000, 100, ((char) 3)); + listener.setAutoApplyMessageSplitterState(true); // Auto apply message splitter to outgoing messages + listener.setConnectionEncryptor(new Base64Encryptor()); // Base 64 Encryption + fConnectedClients = new HashMap<>(); fMainForm = frmMain; } @@ -65,7 +72,8 @@ public void run() { try { - SendToAllClients("Ping" + fSPT); + // Send "Ping" command to all Client + ReplyToAll("Ping" + fSPT); Thread.sleep(5000); } catch (InterruptedException ex) @@ -105,79 +113,78 @@ public void OnDataReceive(TCPClientConnection sender, DataFrame data) { try { - System.out.println(new String(data.getBytes())); + // This isa the client's incoming message String[] splittedMessage = new String(data.getBytes()).split(fSPT); - if (splittedMessage[0].equals("Login")) + switch (splittedMessage[0]) { - /* Message: Login ((char)2) Username - Client wants to login. - Server checks if username is unique. - If the username is taken server replys -> "Change_Username ((char)2)" - If the username is not taken then server replys -> "Welcome ((char)2)" to the new client - and sends "New_User ((char)2) NewUsername" to all other clients. - */ - String tmpUsername = splittedMessage[1]; - if (IsUsernameTaken(tmpUsername)) - { - SendToClient("Change_Username" + fSPT, sender); - } - else - { - TCPChatUser user = new TCPChatUser(tmpUsername, sender); - fConnectedClients.put(sender.getIPAddress(), user); + case "Login": + // Message: Login ((char)2) Username + // Client wants to login. + // Server checks if username is unique. + // If the username is taken server replys -> "Change_Username ((char)2)" + // If the username is not taken then server replys -> "Welcome ((char)2)" to the new client + // and sends "New_User ((char)2) NewUsername" to all other clients. + String tmpUsername = splittedMessage[1]; + if (IsUsernameTaken(tmpUsername)) + { + sender.SendData("Change_Username" + fSPT); + } + else + { + TCPChatUser user = new TCPChatUser(tmpUsername, sender); + fConnectedClients.put(sender.getIPAddress(), user); - SendToAllClients("New_User" + fSPT + tmpUsername); - SendToClient("Welcome" + fSPT, sender); - } - } - else if (splittedMessage[0].equals("Message")) - { - /* Message: Message ((char)2) some_text - Client sends a chat message to the server. - Server checks if the client is registered to the server. - If the client is registered to the server - the server sends this message to all the other clients "Message ((char)2) Sender's username : some_text" else - it disconnects the client. - */ - if (fConnectedClients.containsKey(sender.getIPAddress())) - { - SendToAllClients("Message" + fSPT + GetClientName(sender) + ":" + splittedMessage[1]); - } - else - { - sender.DisconnectMe(); - } - } - else if (splittedMessage[0].equals("Get_List")) - { - /* Message: Get_List ((char)2) - Client requets a list with other connected clients. - If the client is registered to the server the server replys the list - else it disconnects the client. - */ - if (fConnectedClients.containsKey(sender.getIPAddress())) - { - SendToClient(GetConnectedClientsList(), sender); - } - else - { - sender.DisconnectMe(); - } - } - else if (splittedMessage[0].equals("Pong")) - { - /* Message: Pong ((char)2) - Client response to Ping. - */ - System.out.println(GetClientName(sender) + " PONG!"); - } - else - { - System.out.println(sender.getIPAddress() + " sends wrong message"); + super.ReplyToAll("New_User" + fSPT + tmpUsername); + sender.SendData("Welcome" + fSPT); + } + break; + + case "Message": + // Message: Message ((char)2) some_text + // Client sends a chat message to the server. + // Server checks if the client is registered to the server. + // If the client is registered to the server + // the server sends this message to all the other clients "Message ((char)2) Sender's username : some_text" else + // it disconnects the client. + if (fConnectedClients.containsKey(sender.getIPAddress())) + { + super.ReplyToAll("Message" + fSPT + GetClientName(sender) + ":" + splittedMessage[1]); + } + else + { + sender.DisconnectMe(); + } + break; + + case "Get_List": + // Message: Get_List ((char)2) + // Client requets a list with other connected clients. + // If the client is registered to the server the server replys the list + // else it disconnects the client. + if (fConnectedClients.containsKey(sender.getIPAddress())) + { + sender.SendData(GetConnectedClientsList()); + } + else + { + sender.DisconnectMe(); + } + break; + + case "Pong": + // Message: Pong ((char)2) + // A Client responded to Ping. + // Do nothing.... + System.out.println(GetClientName(sender) + " PONG!"); + break; + + default: + System.out.println(sender.getIPAddress() + " sends wrong message"); + break; } } - catch (Exception ex) + catch (ClientIsDisconnectedException | OutgoingPacketFailedException ex) { System.err.println(ex.getMessage()); } @@ -211,44 +218,6 @@ private String GetClientName(TCPClientConnection sender) return ""; } - private void SendToAllClients(String message) - { - message = message + fMCChar; - for (TCPChatUser user : fConnectedClients.values()) - { - try - { - user.SendData(message); - } - catch (ClientIsDisconnectedException | OutgoingPacketFailedException ex) - { - System.err.println(ex.getMessage()); - } - } - - } - - private void SendToClient(String data, TCPClientConnection sender) - { - try - { - sender.SendData(data + fMCChar); - } - catch (ClientIsDisconnectedException ex) - { - // Client disconnected. - System.err.println(ex.getMessage()); - } - catch (OutgoingPacketFailedException ex) - { - // Failed to send packet. - System.err.println(ex.getMessage()); - } - catch (Exception ex) - { - } - } - private String GetConnectedClientsList() { String list = ""; @@ -272,7 +241,7 @@ public void OnClientDisconnect(TCPClientConnection client) { if (fConnectedClients.containsKey(client.getIPAddress())) { - SendToAllClients("Remove_User" + fSPT + ((TCPChatUser) fConnectedClients.get(client.getIPAddress())).getUsername()); + super.ReplyToAll("Remove_User" + fSPT + ((TCPChatUser) fConnectedClients.get(client.getIPAddress())).getUsername()); fConnectedClients.remove(client.getIPAddress()); } fMainForm.UpdateClientsCount(); diff --git a/Extasys for Java Examples/Extasys.Examples.TCPChatServer/src/Extasys/Examples/TCPChatServer/TCPChatUser.java b/Extasys for Java Examples/Extasys.Examples.TCPChatServer/src/Extasys/Examples/TCPChatServer/TCPChatUser.java index e6d91ae..c31a436 100644 --- a/Extasys for Java Examples/Extasys.Examples.TCPChatServer/src/Extasys/Examples/TCPChatServer/TCPChatUser.java +++ b/Extasys for Java Examples/Extasys.Examples.TCPChatServer/src/Extasys/Examples/TCPChatServer/TCPChatUser.java @@ -19,7 +19,6 @@ of this software and associated documentation files (the "Software"), to deal THE SOFTWARE.*/ package Extasys.Examples.TCPChatServer; -import Extasys.Network.TCP.Server.Listener.Exceptions.*; import Extasys.Network.TCP.Server.Listener.TCPClientConnection; /** @@ -29,8 +28,8 @@ of this software and associated documentation files (the "Software"), to deal public class TCPChatUser { - private String fUsername; - private TCPClientConnection fConnection; + private final String fUsername; + private final TCPClientConnection fConnection; public TCPChatUser(String username, TCPClientConnection connection) { @@ -48,8 +47,4 @@ public TCPClientConnection getConnection() return fConnection; } - public void SendData(String data) throws ClientIsDisconnectedException, OutgoingPacketFailedException - { - fConnection.SendData(data); - } } diff --git a/Extasys for Java Examples/Extasys.Examples.TCPClient/nbproject/private/private.xml b/Extasys for Java Examples/Extasys.Examples.TCPClient/nbproject/private/private.xml index 6807a2b..e21765a 100644 --- a/Extasys for Java Examples/Extasys.Examples.TCPClient/nbproject/private/private.xml +++ b/Extasys for Java Examples/Extasys.Examples.TCPClient/nbproject/private/private.xml @@ -2,6 +2,8 @@ - + + file:/C:/Development/extasys/Extasys%20for%20Java%20Examples/Extasys.Examples.TCPClient/src/Extasys/Examples/TCPClient/TCPClient.java + diff --git a/Extasys for Java Examples/Extasys.Examples.TCPClient/src/Extasys/Examples/TCPClient/TCPClient.java b/Extasys for Java Examples/Extasys.Examples.TCPClient/src/Extasys/Examples/TCPClient/TCPClient.java index ce04fa2..10a633c 100644 --- a/Extasys for Java Examples/Extasys.Examples.TCPClient/src/Extasys/Examples/TCPClient/TCPClient.java +++ b/Extasys for Java Examples/Extasys.Examples.TCPClient/src/Extasys/Examples/TCPClient/TCPClient.java @@ -34,19 +34,19 @@ public class TCPClient extends Extasys.Network.TCP.Client.ExtasysTCPClient { private boolean fKeepSendingMessages = false; - private final char fMessageSplitter = (char) 3; private int fPreviousNumber = 0; public TCPClient(String name, String description, InetAddress remoteHostIP, int remoteHostPort, int corePoolSize, int maximumPoolSize) { super(name, description, corePoolSize, maximumPoolSize); + try { - TCPConnector connector = super.AddConnector(name, remoteHostIP, remoteHostPort, 8192, fMessageSplitter); - - // Uncomment the following line to set Encryption for this TCPConnector - connector.setConnectionEncryptor(new Base64Encryptor()); + // Add a new connector to this TCP Client + TCPConnector connector = super.AddConnector(name, remoteHostIP, remoteHostPort, 8192, ((char) 3)); + connector.setAutoApplyMessageSplitterState(true); // Auto apply message splitter to outgoing messages + connector.setConnectionEncryptor(new Base64Encryptor()); // Base 64 Encryption } catch (Exception ex) { @@ -74,7 +74,7 @@ public void OnDataReceive(TCPConnector connector, DataFrame data) // fMessageToExchange string back if (fKeepSendingMessages) { - connector.SendData(String.valueOf(fPreviousNumber) + fMessageSplitter); + connector.SendData(String.valueOf(fPreviousNumber)); } } catch (ConnectorCannotSendPacketException | ConnectorDisconnectedException ex) @@ -102,7 +102,7 @@ public void StartSendingMessages() try { fPreviousNumber = 1000000000; - SendData(String.valueOf(fPreviousNumber) + fMessageSplitter); + SendData(String.valueOf(fPreviousNumber)); } catch (ConnectorDisconnectedException | ConnectorCannotSendPacketException ex) { diff --git a/Extasys for Java Examples/Extasys.Examples.TCPServer/nbproject/private/private.xml b/Extasys for Java Examples/Extasys.Examples.TCPServer/nbproject/private/private.xml index 6807a2b..21d323f 100644 --- a/Extasys for Java Examples/Extasys.Examples.TCPServer/nbproject/private/private.xml +++ b/Extasys for Java Examples/Extasys.Examples.TCPServer/nbproject/private/private.xml @@ -2,6 +2,8 @@ - + + file:/C:/Development/extasys/Extasys%20for%20Java%20Examples/Extasys.Examples.TCPServer/src/Extasys/Examples/TCPServer/TCPServer.java + diff --git a/Extasys for Java Examples/Extasys.Examples.TCPServer/src/Extasys/Examples/TCPServer/TCPServer.java b/Extasys for Java Examples/Extasys.Examples.TCPServer/src/Extasys/Examples/TCPServer/TCPServer.java index 8175d7f..d748261 100644 --- a/Extasys for Java Examples/Extasys.Examples.TCPServer/src/Extasys/Examples/TCPServer/TCPServer.java +++ b/Extasys for Java Examples/Extasys.Examples.TCPServer/src/Extasys/Examples/TCPServer/TCPServer.java @@ -34,21 +34,16 @@ of this software and associated documentation files (the "Software"), to deal public class TCPServer extends Extasys.Network.TCP.Server.ExtasysTCPServer { - private TCPListener fMyTCPListener; - private final char fMessageSplitter = (char) 3; - - public TCPServer(String name, String description, InetAddress listenerIP, int port, int maxConnections, int connectionsTimeOut, int corePoolSize, int maximumPoolSize) { super(name, description, corePoolSize, maximumPoolSize); try { - // Add a listener with message collector. - fMyTCPListener = this.AddListener("My listener", listenerIP, port, maxConnections, 8192, connectionsTimeOut, 100, fMessageSplitter); - - // Uncomment the following line to set Encryption for this TCP listener - fMyTCPListener.setConnectionEncryptor(new Base64Encryptor()); + // Add a new TCPListener to the server + TCPListener listener = super.AddListener("My listener", listenerIP, port, maxConnections, 8192, connectionsTimeOut, 100, (char) 3); + listener.setAutoApplyMessageSplitterState(true); // Auto apply message splitter to outgoing messages + listener.setConnectionEncryptor(new Base64Encryptor()); // Base 64 Encryption } catch (Exception ex) { @@ -62,10 +57,9 @@ public void OnDataReceive(TCPClientConnection sender, DataFrame data) { // I received data from a client final String incomingDataStr = new String(data.getBytes()); - //System.out.println("Data received: " + incomingDataStr); - // Send the incoming data back to the client - sender.SendData(incomingDataStr + fMessageSplitter); + // Send the incoming data back to the sender + sender.SendData(incomingDataStr); } catch (ClientIsDisconnectedException | OutgoingPacketFailedException ex) { diff --git a/Extasys for Java/src/Extasys/MessageCollector/MessageCollector.java b/Extasys for Java/src/Extasys/MessageCollector/MessageCollector.java index 08ac322..60c2a45 100644 --- a/Extasys for Java/src/Extasys/MessageCollector/MessageCollector.java +++ b/Extasys for Java/src/Extasys/MessageCollector/MessageCollector.java @@ -20,6 +20,7 @@ of this software and associated documentation files (the "Software"), to deal package Extasys.MessageCollector; import Extasys.ByteArrayBuilder; +import Extasys.Encryption.ConnectionEncryptor; /** * @@ -37,6 +38,26 @@ public MessageCollector(MessageETX messageETX) fMessageETX = messageETX; } + public synchronized void AppendDataWithDecryption(final byte[] bytes, ConnectionEncryptor encryptor) + { + try + { + fIncomingDataBuffer.Append(bytes); + fIndexOf = fIncomingDataBuffer.IndexOf(fMessageETX.getBytes()); + + while (fIndexOf > -1) + { + MessageCollected(encryptor.Decrypt(fIncomingDataBuffer.SubList(0, fIndexOf))); + fIncomingDataBuffer.Delete(0, fIndexOf + fMessageETX.getLength()); + fIndexOf = fIncomingDataBuffer.IndexOf(fMessageETX.getBytes()); + } + } + catch (Exception ex) + { + //System.err.println("Extasys.Network.TCP.Client.Connectors.Tools.TCPClientMessageCollector Error: " + ex.getMessage()); + } + } + public synchronized void AppendData(final byte[] bytes) { try diff --git a/Extasys for Java/src/Extasys/MessageCollector/MessageETX.java b/Extasys for Java/src/Extasys/MessageCollector/MessageETX.java index f14359a..a442944 100644 --- a/Extasys for Java/src/Extasys/MessageCollector/MessageETX.java +++ b/Extasys for Java/src/Extasys/MessageCollector/MessageETX.java @@ -37,7 +37,7 @@ public MessageETX(byte[] bytes) { fBytes = bytes; } - + public byte[] getBytes() { return fBytes; diff --git a/Extasys for Java/src/Extasys/Network/NetworkPacket.java b/Extasys for Java/src/Extasys/Network/NetworkPacket.java index e6f0e3f..45ee1ce 100644 --- a/Extasys for Java/src/Extasys/Network/NetworkPacket.java +++ b/Extasys for Java/src/Extasys/Network/NetworkPacket.java @@ -76,4 +76,12 @@ public void Cancel() } } + protected byte[] Combine2ByteArrays(byte[] first, byte[] second) + { + byte[] combined = new byte[first.length + second.length]; + System.arraycopy(first, 0, combined, 0, first.length); + System.arraycopy(second, 0, combined, first.length, second.length); + return combined; + } + } diff --git a/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/Packets/IncomingTCPClientPacket.java b/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/Packets/IncomingTCPClientPacket.java index 67c7682..023f9a7 100644 --- a/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/Packets/IncomingTCPClientPacket.java +++ b/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/Packets/IncomingTCPClientPacket.java @@ -57,7 +57,7 @@ protected void SendToThreadPool() { try { - fConnector.fMyTCPClient.fMyThreadPool.execute(this); + fConnector.getMyExtasysTCPClient().getMyThreadPool().execute(this); } catch (RejectedExecutionException ex) { @@ -81,7 +81,7 @@ public void run() final byte[] decryptedData = fConnector.getConnectionEncyptor().Decrypt(fPacketsData); // Call OnDataReceive - fConnector.fMyTCPClient.OnDataReceive(fConnector, new DataFrame(decryptedData)); + fConnector.getMyExtasysTCPClient().OnDataReceive(fConnector, new DataFrame(decryptedData)); } } catch (Exception ex) diff --git a/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/Packets/MessageCollectorTCPClientPacket.java b/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/Packets/MessageCollectorTCPClientPacket.java index f794be5..1be46ee 100644 --- a/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/Packets/MessageCollectorTCPClientPacket.java +++ b/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/Packets/MessageCollectorTCPClientPacket.java @@ -56,7 +56,7 @@ protected void SendToThreadPool() { try { - fConnector.fMyTCPClient.fMyThreadPool.execute(this); + fConnector.getMyExtasysTCPClient().getMyThreadPool().execute(this); } catch (RejectedExecutionException ex) { @@ -77,13 +77,24 @@ public void run() if (!fCancel) { // Decrypt Data - final byte[] decryptedData = fConnector.getConnectionEncyptor().Decrypt(fPacketsData); + if (fConnector.isAutoApplyMessageSplitterOn()) + { + // Append data using AppendDataWithDecryption. + // Message collector decrypts data later + fConnector.fMessageCollector.AppendDataWithDecryption(fPacketsData, fConnector.getConnectionEncyptor()); + } + else + { + // Decrypt data before append + byte[] decyptedData = fConnector.getConnectionEncyptor().Decrypt(fPacketsData); + fConnector.fMessageCollector.AppendData(decyptedData); + } - fConnector.fMessageCollector.AppendData(decryptedData); } } catch (Exception ex) { + } // Mark previous Packet as null. diff --git a/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/Packets/OutgoingTCPClientPacket.java b/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/Packets/OutgoingTCPClientPacket.java index fbc6925..681ea3a 100644 --- a/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/Packets/OutgoingTCPClientPacket.java +++ b/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/Packets/OutgoingTCPClientPacket.java @@ -61,7 +61,7 @@ protected void SendToThreadPool() { try { - fConnector.fMyTCPClient.fMyThreadPool.execute(this); + fConnector.getMyExtasysTCPClient().getMyThreadPool().execute(this); } catch (RejectedExecutionException ex) { @@ -80,14 +80,29 @@ public void run() if (!fCancel) { - // Encrypt Data - final byte[] encryptedData = fConnector.getConnectionEncyptor().Encrypt(fPacketsData); + final byte[] bytesToSent; + + // Check if the MessageSplitter must be applied to the end of + // the encryptedData bytes array to sent. + if (fConnector.isUsingMessageCollector() && fConnector.isAutoApplyMessageSplitterOn()) + { + // Encrypt data + final byte[] encryptedData = fConnector.getConnectionEncyptor().Encrypt(super.fPacketsData); + + // Add ETX to the end of ecnryptedData + bytesToSent = super.Combine2ByteArrays(encryptedData, fConnector.getMessageETX().getBytes()); + } + else + { + // Encrypt Data + bytesToSent = fConnector.getConnectionEncyptor().Encrypt(fPacketsData); + } try { - fConnector.fOutput.write(encryptedData); - fConnector.fBytesOut += encryptedData.length; - fConnector.fMyTCPClient.fTotalBytesOut += encryptedData.length; + fConnector.fOutput.write(bytesToSent); + fConnector.fBytesOut += bytesToSent.length; + fConnector.getMyExtasysTCPClient().fTotalBytesOut += bytesToSent.length; } catch (IOException ioException) { diff --git a/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/TCPConnector.java b/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/TCPConnector.java index 91492c6..0cb9b13 100644 --- a/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/TCPConnector.java +++ b/Extasys for Java/src/Extasys/Network/TCP/Client/Connectors/TCPConnector.java @@ -43,15 +43,15 @@ of this software and associated documentation files (the "Software"), to deal public class TCPConnector { - public ExtasysTCPClient fMyTCPClient; - private final String fName; - private final InetAddress fServerIP; - private final int fServerPort; + protected ExtasysTCPClient fMyTCPClient; + private String fName; + private InetAddress fServerIP; + private int fServerPort; private boolean fActive; protected boolean fIsConnected = false; // Socket properties. public Socket fConnection; - private final int fReadBufferSize; + private int fReadBufferSize; public InputStream fInput; public OutputStream fOutput; protected final Object fSendDataLock = new Object(); @@ -60,9 +60,9 @@ public class TCPConnector // Data throughput. public long fBytesIn = 0, fBytesOut = 0; // Message collector properties. - private boolean fUseMessageCollector; public TCPConnectorMessageCollector fMessageCollector; private MessageETX fMessageETX = null; + private boolean fAutoApplyMessageSplitter = false; // Messages IO. protected NetworkPacket fLastIncomingPacket = null; protected NetworkPacket fLastOutgoingPacket = null; @@ -70,49 +70,70 @@ public class TCPConnector private ConnectionEncryptor fConnectionEncryptor = new NullEncryptor(); /** - * Constructs a new TCP Connector. + * Constructs a new TCP Connector * - * @param myTCPClient is the TCP connector's main Extasys TCP Client. - * @param name is the connector's name. + * @param myExtasysTCPClient is the ExtasysTCPClient of this connector + * @param name is the connector's name * @param serverIP is the server's IP address the connector will use to - * connect. + * connect * @param serverPort is the server's TCP port the connector will use to - * connect. + * connect * @param readBufferSize is the read buffer size in bytes for this - * connection. + * connection * */ - public TCPConnector(ExtasysTCPClient myTCPClient, String name, InetAddress serverIP, int serverPort, int readBufferSize) + public TCPConnector(ExtasysTCPClient myExtasysTCPClient, String name, InetAddress serverIP, int serverPort, int readBufferSize) { - fMyTCPClient = myTCPClient; - fName = name; - fServerIP = serverIP; - fServerPort = serverPort; - fReadBufferSize = readBufferSize; + Initialize(myExtasysTCPClient, name, serverIP, serverPort, readBufferSize, null); } /** - * Constructs a new TCP Connector with message collector use (ETX). + * Constructs a new TCP Connector * - * @param myTCPClient is the TCP connector's main Extasys TCP Client. - * @param name is the connector's name. - * @param serverIP is the server's IP address the connector will connect to. - * @param serverPort is the server's TCP port the connector will connect to. + * @param myExtasysTCPClient is the ExtasysTCPClient of this connector + * @param name is the connector's name + * @param serverIP is the server's IP address the connector will use to + * connect + * @param serverPort is the server's TCP port the connector will use to + * connect * @param readBufferSize is the read buffer size in bytes for this - * connection. - * @param ETX is the End of Text byte[]. + * connection + * @param splitter is the message splitter character */ - public TCPConnector(ExtasysTCPClient myTCPClient, String name, InetAddress serverIP, int serverPort, int readBufferSize, byte[] ETX) + public TCPConnector(ExtasysTCPClient myExtasysTCPClient, String name, InetAddress serverIP, int serverPort, int readBufferSize, char splitter) { - fMyTCPClient = myTCPClient; + Initialize(myExtasysTCPClient, name, serverIP, serverPort, readBufferSize, String.valueOf(splitter).getBytes()); + } + + /** + * Constructs a new TCP Connector + * + * @param myExtasysTCPClient is the ExtasysTCPClient of this connector + * @param name is the connector's name + * @param serverIP is the server's IP address the connector will use to + * connect + * @param serverPort is the server's TCP port the connector will use to + * connect + * @param readBufferSize is the read buffer size in bytes for this + * connection + * @param splitter is the message splitter string + */ + public TCPConnector(ExtasysTCPClient myExtasysTCPClient, String name, InetAddress serverIP, int serverPort, int readBufferSize, String splitter) + { + Initialize(myExtasysTCPClient, name, serverIP, serverPort, readBufferSize, splitter.getBytes()); + } + + private void Initialize(ExtasysTCPClient myExtasysTCPClient, String name, InetAddress serverIP, int serverPort, int readBufferSize, byte[] splitter) + { + fMyTCPClient = myExtasysTCPClient; fName = name; fServerIP = serverIP; fServerPort = serverPort; fReadBufferSize = readBufferSize; - - fUseMessageCollector = true; - fMessageETX = new MessageETX(ETX); - fMessageCollector = new TCPConnectorMessageCollector(this, fMessageETX); + fMessageETX = (splitter != null) ? new MessageETX(splitter) : null; + fMessageCollector = (splitter != null) ? new TCPConnectorMessageCollector(this, fMessageETX) : null; + fBytesIn = 0; + fBytesOut = 0; } /** @@ -240,7 +261,7 @@ private void Stop(boolean force) fReadIncomingDataThread.Dispose(); } - if (fUseMessageCollector) + if (fMessageCollector != null) { fMessageCollector.Dispose(); fMessageCollector = null; @@ -388,9 +409,9 @@ public long getBytesOut() * * @return True if this connector uses message collector. */ - public boolean isMessageCollectorInUse() + public boolean isUsingMessageCollector() { - return fUseMessageCollector; + return fMessageETX != null; } /** @@ -443,6 +464,29 @@ public void setConnectionEncryptor(ConnectionEncryptor encryptor) fConnectionEncryptor = (encryptor == null) ? new NullEncryptor() : encryptor; } + /** + * Returns true if this TCP Connector automatically applies Message Splitter + * to outgoing messages + * + * @return + */ + public boolean isAutoApplyMessageSplitterOn() + { + return fAutoApplyMessageSplitter; + } + + /** + * Sets the Auto-Apply Message Splitter state. If this is set to true then + * Extasys will automatically apply the Message Collector splitter to all + * outgoing messages of this TCP Connector. + * + * @param value + */ + public void setAutoApplyMessageSplitterState(boolean value) + { + fAutoApplyMessageSplitter = value; + } + } /** @@ -491,7 +535,7 @@ public void Dispose() @Override public void run() { - if (fMyTCPConnector.isMessageCollectorInUse()) + if (fMyTCPConnector.isUsingMessageCollector()) { ConnectionWithMessageCollector(); } @@ -516,7 +560,7 @@ private void ConnectionWithMessageCollector() { fMyTCPConnector.fBytesIn += bytesRead; fMyTCPConnector.fMyTCPClient.fTotalBytesIn += bytesRead; - + try { synchronized (fMyTCPConnector.fReceiveDataLock) diff --git a/Extasys for Java/src/Extasys/Network/TCP/Client/ExtasysTCPClient.java b/Extasys for Java/src/Extasys/Network/TCP/Client/ExtasysTCPClient.java index 936189d..8ae5f4c 100644 --- a/Extasys for Java/src/Extasys/Network/TCP/Client/ExtasysTCPClient.java +++ b/Extasys for Java/src/Extasys/Network/TCP/Client/ExtasysTCPClient.java @@ -37,7 +37,7 @@ public abstract class ExtasysTCPClient private String fName, fDescription; private final ArrayList fConnectors = new ArrayList<>(); private final Object fConnectorsLock = new Object(); - public final ExtasysThreadPool fMyThreadPool; + private final ExtasysThreadPool fMyThreadPool; public long fTotalBytesIn = 0, fTotalBytesOut = 0; /** @@ -93,7 +93,7 @@ public TCPConnector AddConnector(String name, InetAddress serverIP, int serverPo { synchronized (fConnectorsLock) { - TCPConnector connector = new TCPConnector(this, name, serverIP, serverPort, readBufferSize, String.valueOf(ETX).getBytes()); + TCPConnector connector = new TCPConnector(this, name, serverIP, serverPort, readBufferSize, ETX); fConnectors.add(connector); return connector; } @@ -114,7 +114,7 @@ public TCPConnector AddConnector(String name, InetAddress serverIP, int serverPo { synchronized (fConnectorsLock) { - TCPConnector connector = new TCPConnector(this, name, serverIP, serverPort, readBufferSize, splitter.getBytes()); + TCPConnector connector = new TCPConnector(this, name, serverIP, serverPort, readBufferSize, splitter); fConnectors.add(connector); return connector; } @@ -187,15 +187,15 @@ private void Stop(boolean force) { synchronized (fConnectorsLock) { - for (int i = 0; i < fConnectors.size(); i++) + for (TCPConnector conn : fConnectors) { if (!force) { - ((TCPConnector) fConnectors.get(i)).Stop(); + conn.Stop(); } else { - ((TCPConnector) fConnectors.get(i)).ForceStop(); + conn.ForceStop(); } } @@ -233,9 +233,9 @@ public void SendData(String data) throws ConnectorDisconnectedException, Connect { synchronized (fConnectorsLock) { - for (int i = 0; i < fConnectors.size(); i++) + for (TCPConnector conn : fConnectors) { - ((TCPConnector) fConnectors.get(i)).SendData(data); + conn.SendData(data); } } } @@ -253,9 +253,9 @@ public void SendData(byte[] bytes) throws ConnectorDisconnectedException, Connec { synchronized (fConnectorsLock) { - for (int i = 0; i < fConnectors.size(); i++) + for (TCPConnector conn : fConnectors) { - ((TCPConnector) fConnectors.get(i)).SendData(bytes); + conn.SendData(bytes); } } } @@ -344,11 +344,9 @@ public ThreadPoolExecutor getMyThreadPool() } /** - * Returns the total number of bytes received from all the connectors of the - * client. + * Returns the total number of bytes received by this client. * - * @return the number of bytes received from all the connectors of the - * client. + * @return the number of bytes received by this client. */ public long getBytesIn() { @@ -356,11 +354,9 @@ public long getBytesIn() } /** - * Returns the total number of bytes send from all the connectors of the - * client. + * Returns the total number of bytes send from this client. * - * @return the total number of bytes send from all the connectors of the - * client. + * @return the total number of bytes send from this client. */ public long getBytesOut() { diff --git a/Extasys for Java/src/Extasys/Network/TCP/Server/ExtasysTCPServer.java b/Extasys for Java/src/Extasys/Network/TCP/Server/ExtasysTCPServer.java index e8b153c..f860ee3 100644 --- a/Extasys for Java/src/Extasys/Network/TCP/Server/ExtasysTCPServer.java +++ b/Extasys for Java/src/Extasys/Network/TCP/Server/ExtasysTCPServer.java @@ -38,7 +38,9 @@ public abstract class ExtasysTCPServer private String fName, fDescription; private final ArrayList fListeners = new ArrayList<>(); - public final ExtasysThreadPool fMyThreadPool; + private final Object fListenersLock = new Object(); + private final ExtasysThreadPool fMyThreadPool; + public long fTotalBytesIn = 0, fTotalBytesOut = 0; /** * Constructs an new Extasys TCP Server. @@ -74,10 +76,12 @@ public ExtasysTCPServer(String name, String description, int corePoolSize, int m */ public TCPListener AddListener(String name, InetAddress ipAddress, int port, int maxConnections, int readBufferSize, int connectionTimeOut, int backLog) { - TCPListener listener = new TCPListener(name, ipAddress, port, maxConnections, readBufferSize, connectionTimeOut, backLog); - listener.setMyExtasysTCPServer(this); - fListeners.add(listener); - return listener; + synchronized (fListenersLock) + { + TCPListener listener = new TCPListener(this, name, ipAddress, port, maxConnections, readBufferSize, connectionTimeOut, backLog); + fListeners.add(listener); + return listener; + } } /** @@ -98,10 +102,12 @@ public TCPListener AddListener(String name, InetAddress ipAddress, int port, int */ public TCPListener AddListener(String name, InetAddress ipAddress, int port, int maxConnections, int readBufferSize, int connectionTimeOut, int backLog, char splitter) { - TCPListener listener = new TCPListener(name, ipAddress, port, maxConnections, readBufferSize, connectionTimeOut, backLog, splitter); - listener.setMyExtasysTCPServer(this); - fListeners.add(listener); - return listener; + synchronized (fListenersLock) + { + TCPListener listener = new TCPListener(this, name, ipAddress, port, maxConnections, readBufferSize, connectionTimeOut, backLog, splitter); + fListeners.add(listener); + return listener; + } } /** @@ -122,10 +128,12 @@ public TCPListener AddListener(String name, InetAddress ipAddress, int port, int */ public TCPListener AddListener(String name, InetAddress ipAddress, int port, int maxConnections, int readBufferSize, int connectionTimeOut, int backLog, String splitter) { - TCPListener listener = new TCPListener(name, ipAddress, port, maxConnections, readBufferSize, connectionTimeOut, backLog, splitter); - listener.setMyExtasysTCPServer(this); - fListeners.add(listener); - return listener; + synchronized (fListenersLock) + { + TCPListener listener = new TCPListener(this, name, ipAddress, port, maxConnections, readBufferSize, connectionTimeOut, backLog, splitter); + fListeners.add(listener); + return listener; + } } /** @@ -135,13 +143,16 @@ public TCPListener AddListener(String name, InetAddress ipAddress, int port, int */ public void RemoveListener(String name) { - for (int i = 0; i < fListeners.size(); i++) + synchronized (fListenersLock) { - if (fListeners.get(i).getName().equals(name)) + for (int i = 0; i < fListeners.size(); i++) { - fListeners.get(i).Stop(); - fListeners.remove(i); - break; + if (fListeners.get(i).getName().equals(name)) + { + fListeners.get(i).Stop(); + fListeners.remove(i); + break; + } } } } @@ -192,25 +203,28 @@ public void ForceStop() private void Stop(boolean force) { - // Stop all listeners. - for (TCPListener listener : fListeners) + synchronized (fListenersLock) { - if (!force) + // Stop all listeners. + for (TCPListener listener : fListeners) { - listener.Stop(); + if (!force) + { + listener.Stop(); + } + else + { + listener.ForceStop(); + } } - else + + try + { + fMyThreadPool.getQueue().clear(); + } + catch (Exception ex) { - listener.ForceStop(); } - } - - try - { - fMyThreadPool.getQueue().clear(); - } - catch (Exception ex) - { } } @@ -285,9 +299,12 @@ public void ReplyToSender(byte[] bytes, TCPClientConnection sender) throws Clien */ public void ReplyToAll(String data) { - for (TCPListener listener : fListeners) + synchronized (fListenersLock) { - listener.ReplyToAll(data); + for (TCPListener listener : fListeners) + { + listener.ReplyToAll(data); + } } } @@ -298,9 +315,12 @@ public void ReplyToAll(String data) */ public void ReplyToAll(byte[] bytes) { - for (TCPListener listener : fListeners) + synchronized (fListenersLock) { - listener.ReplyToAll(bytes); + for (TCPListener listener : fListeners) + { + listener.ReplyToAll(bytes); + } } } @@ -312,9 +332,12 @@ public void ReplyToAll(byte[] bytes) */ public void ReplyToAllExceptSender(String data, TCPClientConnection sender) { - for (TCPListener listener : fListeners) + synchronized (fListenersLock) { - listener.ReplyToAllExceptSender(data, sender); + for (TCPListener listener : fListeners) + { + listener.ReplyToAllExceptSender(data, sender); + } } } @@ -326,9 +349,12 @@ public void ReplyToAllExceptSender(String data, TCPClientConnection sender) */ public void ReplyToAllExceptSender(byte[] bytes, TCPClientConnection sender) { - for (TCPListener listener : fListeners) + synchronized (fListenersLock) { - listener.ReplyToAllExceptSender(bytes, sender); + for (TCPListener listener : fListeners) + { + listener.ReplyToAllExceptSender(bytes, sender); + } } } @@ -380,7 +406,10 @@ public void setDescription(String description) */ public ArrayList getListeners() { - return fListeners; + synchronized (fListenersLock) + { + return fListeners; + } } /** @@ -390,20 +419,23 @@ public ArrayList getListeners() */ public int getCurrentConnectionsNumber() { - int currentConnections = 0; - - for (TCPListener listener : fListeners) + synchronized (fListenersLock) { - try - { - currentConnections += listener.getConnectedClients().size(); - } - catch (Exception ex) + int currentConnections = 0; + + for (TCPListener listener : fListeners) { + try + { + currentConnections += listener.getConnectedClients().size(); + } + catch (Exception ex) + { + } } - } - return currentConnections; + return currentConnections; + } } /** @@ -417,24 +449,13 @@ public ThreadPoolExecutor getMyThreadPool() } /** - * Returns the total bytes received from this server. + * Returns the total bytes received by this server. * - * @return the total bytes received from this server. + * @return the total bytes received by this server. */ public long getBytesIn() { - long bytesIn = 0; - try - { - for (TCPListener listener : fListeners) - { - bytesIn += listener.getBytesIn(); - } - } - catch (Exception ex) - { - } - return bytesIn; + return fTotalBytesIn; } /** @@ -444,17 +465,6 @@ public long getBytesIn() */ public long getBytesOut() { - long bytesOut = 0; - try - { - for (TCPListener listener : fListeners) - { - bytesOut += listener.getBytesOut(); - } - } - catch (Exception ex) - { - } - return bytesOut; + return fTotalBytesOut; } } diff --git a/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/Packets/IncomingTCPClientConnectionPacket.java b/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/Packets/IncomingTCPClientConnectionPacket.java index c69c62b..7cb9ea1 100644 --- a/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/Packets/IncomingTCPClientConnectionPacket.java +++ b/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/Packets/IncomingTCPClientConnectionPacket.java @@ -55,7 +55,7 @@ protected void SendToThreadPool() { try { - fClient.fMyExtasysServer.fMyThreadPool.execute(this); + fClient.fMyExtasysServer.getMyThreadPool().execute(this); } catch (RejectedExecutionException ex) { diff --git a/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/Packets/MessageCollectorTCPClientConnectionPacket.java b/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/Packets/MessageCollectorTCPClientConnectionPacket.java index 7f150f4..fb1e8ac 100644 --- a/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/Packets/MessageCollectorTCPClientConnectionPacket.java +++ b/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/Packets/MessageCollectorTCPClientConnectionPacket.java @@ -57,7 +57,7 @@ protected void SendToThreadPool() { try { - fClient.fMyExtasysServer.fMyThreadPool.execute(this); + fClient.fMyExtasysServer.getMyThreadPool().execute(this); } catch (RejectedExecutionException ex) { @@ -78,10 +78,19 @@ public void run() if (!fCancel) { // Decrypt Data - final byte[] decryptedData = fClient.getMyTCPListener().getConnectionEncyptor().Decrypt(fPacketsData); - - // Append Data to Message Collector - fClient.fMyMessageCollector.AppendData(decryptedData); + if (fClient.fMyListener.isAutoApplyMessageSplitterOn()) + { + // Append data as using AppendDataWithDecryption. + // Message collector decrypts data later + fClient.fMyMessageCollector.AppendDataWithDecryption(fPacketsData, fClient.fMyListener.getConnectionEncyptor()); + } + else + { + // Decrypt data before append + byte[] decyptedData = fClient.getMyTCPListener().getConnectionEncyptor().Decrypt(fPacketsData); + fClient.fMyMessageCollector.AppendData(decyptedData); + } + } } catch (Exception ex) diff --git a/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/Packets/OutgoingTCPClientConnectionPacket.java b/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/Packets/OutgoingTCPClientConnectionPacket.java index 38bc5d1..41f1171 100644 --- a/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/Packets/OutgoingTCPClientConnectionPacket.java +++ b/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/Packets/OutgoingTCPClientConnectionPacket.java @@ -59,7 +59,7 @@ protected void SendToThreadPool() { try { - fClient.fMyExtasysServer.fMyThreadPool.execute(this); + fClient.fMyExtasysServer.getMyThreadPool().execute(this); } catch (RejectedExecutionException ex) { @@ -78,14 +78,30 @@ public void run() if (!fCancel) { - // Encrypt data before Sent - final byte[] encryptedData = fClient.getMyTCPListener().getConnectionEncyptor().Encrypt(super.fPacketsData); + final byte[] bytesToSent; + + // Check if the MessageSplitter must be applied to the end of + // the encryptedData bytes array to sent. + if (fClient.fMyListener.isUsingMessageCollector() && fClient.fMyListener.isAutoApplyMessageSplitterOn()) + { + // Encrypt data + final byte[] encryptedData = fClient.getMyTCPListener().getConnectionEncyptor().Encrypt(super.fPacketsData); + + // Add ETX to the end of ecnryptedData + bytesToSent = super.Combine2ByteArrays(encryptedData, fClient.fMyListener.getMessageETX().getBytes()); + } + else + { + // Encrypt data before Sent + bytesToSent = fClient.getMyTCPListener().getConnectionEncyptor().Encrypt(super.fPacketsData); + } try { - fClient.fOutput.write(encryptedData); - fClient.fBytesOut += encryptedData.length; - fClient.fMyListener.fBytesOut += encryptedData.length; + fClient.fOutput.write(bytesToSent); + fClient.fBytesOut += bytesToSent.length; + fClient.fMyListener.fBytesOut += bytesToSent.length; + fClient.fMyExtasysServer.fTotalBytesOut += bytesToSent.length; } catch (IOException ioException) { diff --git a/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/TCPClientConnection.java b/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/TCPClientConnection.java index da0f365..cf97d80 100644 --- a/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/TCPClientConnection.java +++ b/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/TCPClientConnection.java @@ -415,6 +415,7 @@ private void ClientWithMessageCollector() { fClientConnection.fBytesIn += bytesRead; fClientConnection.fMyListener.fBytesIn += bytesRead; + fClientConnection.fMyExtasysServer.fTotalBytesIn += bytesRead; // PACKET WITH MESSAGE COLLECTOR synchronized (fClientConnection.fReceiveDataLock) @@ -452,6 +453,7 @@ private void ClientWithoutMessageCollector() { fClientConnection.fBytesIn += bytesRead; fClientConnection.fMyListener.fBytesIn += bytesRead; + fClientConnection.fMyExtasysServer.fTotalBytesIn += bytesRead; // PACKET WITHOUT MESSAGE COLLECTOR synchronized (fClientConnection.fReceiveDataLock) diff --git a/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/TCPListener.java b/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/TCPListener.java index 3aa7844..95a10d2 100644 --- a/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/TCPListener.java +++ b/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/TCPListener.java @@ -55,73 +55,77 @@ public class TCPListener // Bytes throughtput. public long fBytesIn, fBytesOut; // Message collector. - private boolean fUseMessageCollector = false; private MessageETX fMessageETX = null; + private boolean fAutoApplyMessageSplitter = false; // Connection Encryption private ConnectionEncryptor fConnectionEncryptor = new NullEncryptor(); /** * Constructs a new TCP listener. * - * @param name is the listener's name. - * @param ipAddress is the listener's IP Address. - * @param port is the listener's port. - * @param maxConnections is the listener's maximum connections limit. + * @param myServer is the Extasys TCP Server of this listener + * @param name is the listener's name + * @param ipAddress is the listener's IP Address + * @param port is the listener's port + * @param maxConnections is the listener's maximum connections limit * @param readBufferSize is the listener's each connection read buffer size - * in bytes. + * in bytes * @param connectionTimeOut is the listener's connections time-out time in - * milliseconds. + * milliseconds * @param backLog is the number of outstanding connection requests this - * listener can have. + * listener can have * */ - public TCPListener(String name, InetAddress ipAddress, int port, int maxConnections, int readBufferSize, int connectionTimeOut, int backLog) + public TCPListener(ExtasysTCPServer myServer, String name, InetAddress ipAddress, int port, int maxConnections, int readBufferSize, int connectionTimeOut, int backLog) { - Initialize(name, ipAddress, port, maxConnections, readBufferSize, connectionTimeOut, backLog, false, null); + Initialize(myServer, name, ipAddress, port, maxConnections, readBufferSize, connectionTimeOut, backLog, false, null); } /** - * Constructs a new TCP listener. + * Constructs a new TCP listener * - * @param name is the listener's name. - * @param ipAddress is the listener's IP Address. - * @param port is the listener's port. - * @param maxConnections is the listener's maximum allowed connections.. + * @param myServer is the Extasys TCP Server of this listener + * @param name is the listener's name + * @param ipAddress is the listener's IP Address + * @param port is the listener's port + * @param maxConnections is the listener's maximum allowed connections * @param readBufferSize is the listener's each connection read buffer size - * in bytes. + * in bytes * @param connectionTimeOut is the listener's connections time-out in * milliseconds. Set to 0 for no time-out * @param backLog is the number of outstanding connection requests this - * listener can have. - * @param splitter is the message splitter. + * listener can have + * @param splitter is the message splitter */ - public TCPListener(String name, InetAddress ipAddress, int port, int maxConnections, int readBufferSize, int connectionTimeOut, int backLog, char splitter) + public TCPListener(ExtasysTCPServer myServer, String name, InetAddress ipAddress, int port, int maxConnections, int readBufferSize, int connectionTimeOut, int backLog, char splitter) { - Initialize(name, ipAddress, port, maxConnections, readBufferSize, connectionTimeOut, backLog, true, String.valueOf(splitter).getBytes()); + Initialize(myServer, name, ipAddress, port, maxConnections, readBufferSize, connectionTimeOut, backLog, true, String.valueOf(splitter).getBytes()); } /** - * Constructs a new TCP listener. + * Constructs a new TCP listener * - * @param name is the listener's name. - * @param ipAddress is the listener's IP Address. - * @param port is the listener's port. - * @param maxConnections is the listener's maximum allowed connections.. + * @param myServer is the Extasys TCP Server of this listener + * @param name is the listener's name + * @param ipAddress is the listener's IP Address + * @param port is the listener's port + * @param maxConnections is the listener's maximum allowed connections * @param readBufferSize is the listener's each connection read buffer size - * in bytes. + * in bytes * @param connectionTimeOut is the listener's connections time-out in * milliseconds. Set to 0 for no time-out * @param backLog is the number of outstanding connection requests this - * listener can have. - * @param splitter is the message splitter. + * listener can have + * @param splitter is the message splitter */ - public TCPListener(String name, InetAddress ipAddress, int port, int maxConnections, int readBufferSize, int connectionTimeOut, int backLog, String splitter) + public TCPListener(ExtasysTCPServer myServer, String name, InetAddress ipAddress, int port, int maxConnections, int readBufferSize, int connectionTimeOut, int backLog, String splitter) { - Initialize(name, ipAddress, port, maxConnections, readBufferSize, connectionTimeOut, backLog, true, splitter.getBytes()); + Initialize(myServer, name, ipAddress, port, maxConnections, readBufferSize, connectionTimeOut, backLog, true, splitter.getBytes()); } - private void Initialize(String name, InetAddress ipAddress, int port, int maxConnections, int readBufferSize, int connectionTimeOut, int backLog, boolean useMessageCollector, byte[] splitter) + private void Initialize(ExtasysTCPServer myServer, String name, InetAddress ipAddress, int port, int maxConnections, int readBufferSize, int connectionTimeOut, int backLog, boolean useMessageCollector, byte[] splitter) { + fMyExtasysTCPServer = myServer; fConnectedClients = new HashMap<>(); fName = name; fIPAddress = ipAddress; @@ -130,17 +134,13 @@ private void Initialize(String name, InetAddress ipAddress, int port, int maxCon fReadBufferSize = readBufferSize; fConnectionTimeOut = connectionTimeOut; fBackLog = backLog; - fUseMessageCollector = useMessageCollector; - if (splitter != null) - { - fMessageETX = new MessageETX(splitter); - } + fMessageETX = (splitter != null) ? new MessageETX(splitter) : null; fBytesIn = 0; fBytesOut = 0; } /** - * Start or restart the TCPListener. + * Start or restart the TCPListener * * @throws java.io.IOException */ @@ -172,7 +172,7 @@ public void Start() throws IOException, Exception } /** - * Stop the TCP listener. + * Stop the TCP listener */ public void Stop() { @@ -383,17 +383,6 @@ public ServerSocket getServerSocket() return fTcpListener; } - /** - * Set my Extasys TCP server. - * - * @param server is the ExtasysTCPServer main reference at witch this - * TCPListener belongs. - */ - public void setMyExtasysTCPServer(ExtasysTCPServer server) - { - fMyExtasysTCPServer = server; - } - /** * Returns a reference of this listener's main Extasys TCP server. * @@ -544,9 +533,9 @@ public long getBytesOut() * * @return True if the message collector of this listener is active. */ - public boolean isMessageCollectorInUse() + public boolean isUsingMessageCollector() { - return fUseMessageCollector; + return fMessageETX != null; } /** @@ -579,4 +568,27 @@ public void setConnectionEncryptor(ConnectionEncryptor encryptor) fConnectionEncryptor = (encryptor == null) ? new NullEncryptor() : encryptor; } + /** + * Returns true if this TCP Listener automatically applies Message Splitter + * to outgoing messages + * + * @return + */ + public boolean isAutoApplyMessageSplitterOn() + { + return fAutoApplyMessageSplitter; + } + + /** + * Sets the Auto-Apply Message Splitter state. If this is set to true then + * Extasys will automatically apply the Message Collector splitter to all + * outgoing messages of this TCP Listener. + * + * @param value + */ + public void setAutoApplyMessageSplitterState(boolean value) + { + fAutoApplyMessageSplitter = value; + } + } diff --git a/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/TCPListenerThread.java b/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/TCPListenerThread.java index d343181..7c06c55 100644 --- a/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/TCPListenerThread.java +++ b/Extasys for Java/src/Extasys/Network/TCP/Server/Listener/TCPListenerThread.java @@ -47,7 +47,7 @@ public void run() { try { - TCPClientConnection client = new TCPClientConnection(fSocket.accept(), fMyListener, fMyListener.isMessageCollectorInUse(), fMyListener.getMessageETX()); + TCPClientConnection client = new TCPClientConnection(fSocket.accept(), fMyListener, fMyListener.isUsingMessageCollector(), fMyListener.getMessageETX()); if (fMyListener.getConnectedClients().size() >= fMyListener.getMaxConnections()) { client.DisconnectMe(); diff --git a/Extasys for Java/src/Extasys/Network/UDP/Client/Connectors/Packets/OutgoingUDPClientPacket.java b/Extasys for Java/src/Extasys/Network/UDP/Client/Connectors/Packets/OutgoingUDPClientPacket.java index 3a8c7de..6416d94 100644 --- a/Extasys for Java/src/Extasys/Network/UDP/Client/Connectors/Packets/OutgoingUDPClientPacket.java +++ b/Extasys for Java/src/Extasys/Network/UDP/Client/Connectors/Packets/OutgoingUDPClientPacket.java @@ -71,6 +71,7 @@ public void run() { fConnector.fSocket.send(fDataGram); fConnector.fBytesOut += fDataGram.getLength(); + fConnector.getMyExtasysUDPClient().fTotalBytesOut += fDataGram.getLength(); } } catch (IOException ex) diff --git a/Extasys for Java/src/Extasys/Network/UDP/Client/Connectors/UDPConnector.java b/Extasys for Java/src/Extasys/Network/UDP/Client/Connectors/UDPConnector.java index bbca48c..06d78e1 100644 --- a/Extasys for Java/src/Extasys/Network/UDP/Client/Connectors/UDPConnector.java +++ b/Extasys for Java/src/Extasys/Network/UDP/Client/Connectors/UDPConnector.java @@ -296,14 +296,13 @@ public void run() receivedPacket = new DatagramPacket(data, data.length); fMyConnector.fSocket.receive(receivedPacket); fMyConnector.fBytesIn += receivedPacket.getLength(); + fMyConnector.getMyExtasysUDPClient().fTotalBytesIn += receivedPacket.getLength(); fMyConnector.fLastIncomingPacket = new IncomingUDPClientPacket(fMyConnector, receivedPacket, fMyConnector.fLastIncomingPacket); } catch (IOException ex) { - } - catch (Exception ex) - { + fMyConnector.Stop(); } } } diff --git a/Extasys for Java/src/Extasys/Network/UDP/Client/ExtasysUDPClient.java b/Extasys for Java/src/Extasys/Network/UDP/Client/ExtasysUDPClient.java index 301469d..84c61bb 100644 --- a/Extasys for Java/src/Extasys/Network/UDP/Client/ExtasysUDPClient.java +++ b/Extasys for Java/src/Extasys/Network/UDP/Client/ExtasysUDPClient.java @@ -32,12 +32,14 @@ of this software and associated documentation files (the "Software"), to deal * * @author Nikos Siatras */ -public class ExtasysUDPClient +public abstract class ExtasysUDPClient { private String fName, fDescription; private final ArrayList fConnectors = new ArrayList<>(); + private final Object fConnectorsLock = new Object(); private final ExtasysThreadPool fMyThreadPool; + public long fTotalBytesIn = 0, fTotalBytesOut = 0; /** * Constructs a new Extasys UDP Client. @@ -70,9 +72,12 @@ public ExtasysUDPClient(String name, String description, int corePoolSize, int m */ public UDPConnector AddConnector(String name, int readBufferSize, int readTimeOut, InetAddress serverIP, int serverPort) { - UDPConnector connector = new UDPConnector(this, name, readBufferSize, readTimeOut, serverIP, serverPort); - fConnectors.add(connector); - return connector; + synchronized (fConnectorsLock) + { + UDPConnector connector = new UDPConnector(this, name, readBufferSize, readTimeOut, serverIP, serverPort); + fConnectors.add(connector); + return connector; + } } /** @@ -82,13 +87,16 @@ public UDPConnector AddConnector(String name, int readBufferSize, int readTimeOu */ public void RemoveConnector(String name) { - for (int i = 0; i < fConnectors.size(); i++) + synchronized (fConnectorsLock) { - if (((UDPConnector) fConnectors.get(i)).getName().equals(name)) + for (int i = 0; i < fConnectors.size(); i++) { - ((UDPConnector) fConnectors.get(i)).Stop(); - fConnectors.remove(i); - break; + if (((UDPConnector) fConnectors.get(i)).getName().equals(name)) + { + ((UDPConnector) fConnectors.get(i)).Stop(); + fConnectors.remove(i); + break; + } } } } @@ -101,9 +109,12 @@ public void RemoveConnector(String name) */ public void SendData(String data) throws IOException { - for (UDPConnector conn : fConnectors) + synchronized (fConnectorsLock) { - conn.SendData(data); + for (UDPConnector conn : fConnectors) + { + conn.SendData(data); + } } } @@ -115,9 +126,12 @@ public void SendData(String data) throws IOException */ public void SendData(byte[] bytes) throws IOException { - for (UDPConnector conn : fConnectors) + synchronized (fConnectorsLock) { - conn.SendData(bytes); + for (UDPConnector conn : fConnectors) + { + conn.SendData(bytes); + } } } @@ -128,17 +142,20 @@ public void SendData(byte[] bytes) throws IOException */ public void Start() throws SocketException, Exception { - Stop(); - try + synchronized (fConnectorsLock) { - for (UDPConnector conn : fConnectors) + Stop(); + try { - conn.Start(); + for (UDPConnector conn : fConnectors) + { + conn.Start(); + } + } + catch (SocketException ex) + { + throw ex; } - } - catch (SocketException ex) - { - throw ex; } } @@ -147,15 +164,18 @@ public void Start() throws SocketException, Exception */ public void Stop() { - try + synchronized (fConnectorsLock) { - for (UDPConnector conn : fConnectors) + try + { + for (UDPConnector conn : fConnectors) + { + conn.Stop(); + } + } + catch (Exception ex) { - conn.Stop(); } - } - catch (Exception ex) - { } } @@ -170,12 +190,7 @@ public void Dispose() fMyThreadPool.shutdown(); } - public void OnDataReceive(UDPConnector connector, DatagramPacket packet) - { - //System.out.println("Data received"); - //System.out.println("---" + packet.getAddress() + ":" + packet.getPort()); - //System.out.println("---" + new String(packet.getData(), 0, packet.getLength())); - } + public abstract void OnDataReceive(UDPConnector connector, DatagramPacket packet); /** * Return the name of the UDP client. @@ -245,18 +260,7 @@ public ThreadPoolExecutor getMyThreadPool() */ public long getBytesIn() { - long result = 0; - try - { - for (UDPConnector conn : fConnectors) - { - result += conn.getBytesIn(); - } - } - catch (Exception ex) - { - } - return result; + return fTotalBytesIn; } /** @@ -266,18 +270,7 @@ public long getBytesIn() */ public long getBytesOut() { - long result = 0; - try - { - for (UDPConnector conn : fConnectors) - { - result += conn.getBytesOut(); - } - } - catch (Exception ex) - { - } - return result; + return fTotalBytesOut; } } diff --git a/Extasys for Java/src/Extasys/Network/UDP/Server/ExtasysUDPServer.java b/Extasys for Java/src/Extasys/Network/UDP/Server/ExtasysUDPServer.java index 5aaa933..eb84b21 100644 --- a/Extasys for Java/src/Extasys/Network/UDP/Server/ExtasysUDPServer.java +++ b/Extasys for Java/src/Extasys/Network/UDP/Server/ExtasysUDPServer.java @@ -30,12 +30,14 @@ of this software and associated documentation files (the "Software"), to deal * * @author Nikos Siatras */ -public class ExtasysUDPServer +public abstract class ExtasysUDPServer { private String fName, fDescription; private final ArrayList fListeners = new ArrayList<>(); + private final Object fListenersLock = new Object(); public final ExtasysThreadPool fMyThreadPool; + public long fTotalBytesIn = 0, fTotalBytesOut = 0; /** * Constructs a new Extasys UDP Server. @@ -68,9 +70,12 @@ public ExtasysUDPServer(String name, String description, int corePoolSize, int m */ public UDPListener AddListener(String name, InetAddress ipAddress, int port, int readBufferSize, int readDataTimeOut) { - UDPListener listener = new UDPListener(this, name, ipAddress, port, readBufferSize, readDataTimeOut); - fListeners.add(listener); - return listener; + synchronized (fListenersLock) + { + UDPListener listener = new UDPListener(this, name, ipAddress, port, readBufferSize, readDataTimeOut); + fListeners.add(listener); + return listener; + } } /** @@ -98,9 +103,12 @@ public void RemoveListener(String name) */ public void SendData(DatagramPacket packet) { - for (UDPListener listener : fListeners) + synchronized (fListenersLock) { - listener.SendData(packet); + for (UDPListener listener : fListeners) + { + listener.SendData(packet); + } } } @@ -111,11 +119,14 @@ public void SendData(DatagramPacket packet) */ public void Start() throws SocketException { - Stop(); - - for (UDPListener listener : fListeners) + synchronized (fListenersLock) { - listener.Start(); + Stop(); + + for (UDPListener listener : fListeners) + { + listener.Start(); + } } } @@ -124,9 +135,12 @@ public void Start() throws SocketException */ public void Stop() { - for (UDPListener listener : fListeners) + synchronized (fListenersLock) { - listener.Stop(); + for (UDPListener listener : fListeners) + { + listener.Stop(); + } } } @@ -141,15 +155,7 @@ public void Dispose() fMyThreadPool.shutdown(); } - public void OnDataReceive(UDPListener listener, DatagramPacket packet) - { - //System.out.println("Data received"); - //System.out.println("---" + packet.getAddress() + ":" + packet.getPort()); - //System.out.println("---" + new String(packet.getData(), 0, packet.getLength(), listener.getCharset())); - - //DatagramPacket reply = new DatagramPacket(packet.getData(), 0, packet.getLength(), packet.getAddress(), packet.getPort()); - //listener.SendData(reply); - } + public abstract void OnDataReceive(UDPListener listener, DatagramPacket packet); /** * Returns the name of this UDP server. @@ -209,18 +215,7 @@ public ArrayList getListeners() */ public long getBytesIn() { - long bytesIn = 0; - try - { - for (UDPListener listener : fListeners) - { - bytesIn += listener.getBytesIn(); - } - } - catch (Exception ex) - { - } - return bytesIn; + return fTotalBytesIn; } /** @@ -230,17 +225,6 @@ public long getBytesIn() */ public long getBytesOut() { - long bytesOut = 0; - try - { - for (UDPListener listener : fListeners) - { - bytesOut += listener.getBytesOut(); - } - } - catch (Exception ex) - { - } - return bytesOut; + return fTotalBytesOut; } } diff --git a/Extasys for Java/src/Extasys/Network/UDP/Server/Listener/Packets/OutgoingUDPServerPacket.java b/Extasys for Java/src/Extasys/Network/UDP/Server/Listener/Packets/OutgoingUDPServerPacket.java index da55a24..1c4879f 100644 --- a/Extasys for Java/src/Extasys/Network/UDP/Server/Listener/Packets/OutgoingUDPServerPacket.java +++ b/Extasys for Java/src/Extasys/Network/UDP/Server/Listener/Packets/OutgoingUDPServerPacket.java @@ -60,13 +60,14 @@ public void run() { fMyListener.fSocket.send(fDataGram); fMyListener.fBytesOut += fDataGram.getLength(); + fMyListener.getMyExtasysUDPServer().fTotalBytesOut += fDataGram.getLength(); } } catch (Exception ex) { } - + // Mark previous Packet as null. // GC will take it out later... fPreviousPacket = null; diff --git a/Extasys for Java/src/Extasys/Network/UDP/Server/Listener/UDPListener.java b/Extasys for Java/src/Extasys/Network/UDP/Server/Listener/UDPListener.java index 232e9f2..2decf74 100644 --- a/Extasys for Java/src/Extasys/Network/UDP/Server/Listener/UDPListener.java +++ b/Extasys for Java/src/Extasys/Network/UDP/Server/Listener/UDPListener.java @@ -281,6 +281,7 @@ public void run() receivedPacket = new DatagramPacket(data, data.length); fMyUDPListener.fSocket.receive(receivedPacket); fMyUDPListener.fBytesIn += receivedPacket.getLength(); + fMyUDPListener.getMyExtasysUDPServer().fTotalBytesIn += receivedPacket.getLength(); fMyUDPListener.fLastIncomingPacket = new IncomingUDPServerPacket(fMyUDPListener, receivedPacket, fMyUDPListener.fLastIncomingPacket); } diff --git a/Extasys for Java/src/Extasys/Settings/Settings.java b/Extasys for Java/src/Extasys/Settings/Settings.java index c2ccb98..43a56fa 100644 --- a/Extasys for Java/src/Extasys/Settings/Settings.java +++ b/Extasys for Java/src/Extasys/Settings/Settings.java @@ -26,5 +26,5 @@ of this software and associated documentation files (the "Software"), to deal public class Settings { - public static final String VERSION = "Extasys NT v1.0.3"; + public static final String VERSION = "Extasys NT v1.0.4"; }