TCP Sockets Library

Discussion in 'Resources' started by MCManager, Jan 18, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    MCManager

    Now, you maybe asking yourself, what is a socket? Well, here is a basic definition:



    Put more simply,


    Okay, so now that that's out of the way, I can explain what the library actually does.

    This library makes it simpler to create server/client sockets with fewer lines of code. It is event-driven, so when a message has been received by either the server or client, it fires an event, which then can be processed by your code. The same goes for connecting, disconnecting, etc...



    Normally, a basic client socket would be something like:

    Code:java
    1. import java.io.*;
    2. import java.net.*;
    3.  
    4. public class Requester
    5. {
    6. Socket requestSocket;
    7. String message;
    8.  
    9. Requester()
    10. {
    11. }
    12.  
    13. void run()
    14. {
    15. try
    16. {
    17. //1. creating a socket to connect to the server
    18. requestSocket = new Socket("localhost", 2004);
    19. System.out.println("Connected to localhost in port 2004");
    20. //2. get Input and Output streams
    21. out = new ObjectOutputStream(requestSocket.getOutputStream());
    22. out.flush();
    23. in = new ObjectInputStream(requestSocket.getInputStream());
    24. //3: Communicating with the server
    25. do
    26. {
    27. try
    28. {
    29. message = (String) in.readObject();
    30. System.out.println("server>" + message);
    31. sendMessage("Hi my server");
    32. message = "bye";
    33. sendMessage(message);
    34. }
    35. catch (ClassNotFoundException classNot)
    36. {
    37. System.err.println("data received in unknown format");
    38. }
    39. }
    40. while (!message.equals("bye"));
    41. }
    42. catch (UnknownHostException unknownHost)
    43. {
    44. System.err.println("You are trying to connect to an unknown host!");
    45. }
    46. catch (IOException ioException)
    47. {
    48. ioException.printStackTrace();
    49. }
    50. finally
    51. {
    52. //4: Closing connection
    53. try
    54. {
    55. in.close();
    56. out.close();
    57. requestSocket.close();
    58. }
    59. catch (IOException ioException)
    60. {
    61. ioException.printStackTrace();
    62. }
    63. }
    64. }
    65.  
    66. void sendMessage(String msg)
    67. {
    68. try
    69. {
    70. out.writeObject(msg);
    71. out.flush();
    72. System.out.println("client>" + msg);
    73. }
    74. catch (IOException ioException)
    75. {
    76. ioException.printStackTrace();
    77. }
    78. }
    79.  
    80. public static void main(String args[])
    81. {
    82. Requester client = new Requester();
    83. client.run();
    84. }
    85. }



    But using this library, it can be simplified into:

    Code:java
    1. public class SocketExample extends JavaPlugin
    2. {
    3. private final Server server = new Server(9876);
    4. private final Client client = new Client("127.0.0.1", 9876);
    5. private Logger logger = Logger.getLogger("Minecraft");
    6.  
    7. public void onDisable()
    8. {
    9. client.Disconnect();
    10. server.ShutdownAll();
    11. server.StopServer();
    12. }
    13.  
    14. public void onEnable()
    15. {
    16. client.getHandler().getConnected().addSocketConnectedEventListener(new SocketConnectedEventListener()
    17. {
    18.  
    19. @Override
    20. public void socketConnected(SocketConnectedEvent evt)
    21. {
    22.  
    23. logger.info("Client - Connected to server!");
    24. logger.info("Client - Sending message to server.");
    25.  
    26. client.SendMessage("Hello World!");
    27.  
    28. }
    29. });
    30.  
    31. client.getHandler().getMessage().addMessageReceivedEventListener(new MessageReceivedEventListener()
    32. {
    33. @Override
    34. public void messageReceived(MessageReceivedEvent evt)
    35. {
    36.  
    37. logger.info("Client - I got the following message: " + evt.getMessage());
    38.  
    39. client.Disconnect();
    40.  
    41. }
    42. });
    43.  
    44. }
    45. }




    Source Code

    Example Source Code

    Download JAR



    Some extra info on sockets:

    The TCP/IP protocol is stream-oriented; it was not made for sending/receiving messages. Basically, as I understand it, when sending a "message" through a socket, the whole thing is not sent as "one message." The data is streamed, so when the client starts reading, it doesn't know where the message you sent starts or ends. This can result in broken up messages.

    Example:

    Server sends: Hello World
    Client receives: Hel
    Client receives: lo World


    There are several methods on receiving full messages, without it being broken up. One way would be to use a delimiter, which splits the message by a certain character(s). Another method, which I used, was to send the message with a header, which tells the server/client what the length of the message will be. So, when it receives a message, it first reads the first four bytes, which contains the header, then stores the length received into an integer. After that, it reads again and again until it receives the full message using the length that was received previously.



    Note: I haven't tested it very thoroughly, so if you find any bugs or want something added, feel free to post here.


    P.S: This library only supports sending/receiving strings at the moment, but that can be changed if needed.
     
    DrAgonmoray likes this.
  2. Offline

    slothario

    Thanks for this! I'm going to use it in my own plugin.
     
  3. Offline

    thehutch

    Could you list some usages of this library?
     
  4. Offline

    Killie01

    Well, sending messages between an application and your plugin, or communicate with other plugins that you made.
     
  5. Offline

    soliddanii

    hello, how can I add the MessageRecievedEvent Listener to a java application? Not to a plugin, because I want my application to show The info when it is recieved from ther server. Thanks
     
  6. in.close();
    out.close();
    requestSocket.close();
    They may be null on the time that code comes there, you know?
     
  7. Offline

    dr0n3

    I'll get a "ClassNotFoundExeception".
    The library ist included into NetBeans (Properties - Libraries - Add Jar/Folder).
    Any suggestions to fix that?

    Code:
    org.bukkit.plugin.InvalidPluginException: java.lang.NoClassDefFoundError: com/mitch528/sockets/events/ServerSocketAcceptedEventListener
        at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:155)
        at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.java:305)
        at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:230)
        at org.bukkit.craftbukkit.CraftServer.loadPlugins(CraftServer.java:222)
        at org.bukkit.craftbukkit.CraftServer.<init>(CraftServer.java:198)
        at net.minecraft.server.ServerConfigurationManagerAbstract.<init>(ServerConfigurationManagerAbstract.java:50)
        at net.minecraft.server.ServerConfigurationManager.<init>(SourceFile:11)
        at net.minecraft.server.DedicatedServer.init(DedicatedServer.java:105)
        at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:378)
        at net.minecraft.server.ThreadServerApplication.run(SourceFile:539)
    Caused by: java.lang.NoClassDefFoundError: com/mitch528/sockets/events/ServerSocketAcceptedEventListener
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:144)
        ... 9 more
    Caused by: java.lang.ClassNotFoundException: com.mitch528.sockets.events.ServerSocketAcceptedEventListener
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:44)
        at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:29)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 12 more
     
  8. I'm receiving a StackOverflow error after that the plugin has been running for a little bit, about 5 minutes. Do keep in mind that this is a Bungee stack trace because I made Bungee my server instance.
    Code:
    11:36:16 [SEVERE] Exception in thread "Thread-5"
    11:36:16 [SEVERE] java.lang.StackOverflowError
    11:36:16 [SEVERE]    at java.util.regex.Pattern.expr(Pattern.java:1996)
    11:36:16 [SEVERE]    at java.util.regex.Pattern.compile(Pattern.java:1696)
    11:36:16 [SEVERE]    at java.util.regex.Pattern.<init>(Pattern.java:1351)
    11:36:16 [SEVERE]    at java.util.regex.Pattern.compile(Pattern.java:1028)
    11:36:16 [SEVERE]    at java.lang.String.split(String.java:2367)
    11:36:16 [SEVERE]    at java.lang.String.split(String.java:2409)
    11:36:16 [SEVERE]    at me.Markcreator.FlareBungeeSocket.SocketMessage.<init>(SocketMessage.java:13)
    11:36:16 [SEVERE]    at me.Markcreator.FlareBungeeSocket.Main$1$1.messageReceived(Main.java:68)
    11:36:16 [SEVERE]    at me.Markcreator.FlareBungeeSocket.events.MessageReceived.executeEvent(MessageReceived.java:28)
    11:36:16 [SEVERE]    at me.Markcreator.FlareBungeeSocket.Sockets.SocketHandler.startReading(SocketHandler.java:172)
    11:36:16 [SEVERE]    at me.Markcreator.FlareBungeeSocket.Sockets.SocketHandler.startReading(SocketHandler.java:158)
    11:36:16 [SEVERE]    at me.Markcreator.FlareBungeeSocket.Sockets.SocketHandler.startReading(SocketHandler.java:179)
    11:36:16 [SEVERE]    at me.Markcreator.FlareBungeeSocket.Sockets.SocketHandler.startReading(SocketHandler.java:158)
    11:36:16 [SEVERE]    at me.Markcreator.FlareBungeeSocket.Sockets.SocketHandler.startReading(SocketHandler.java:179)
    ECT ECT ECT ECT ECT
    11:36:16 [SEVERE]    at me.Markcreator.FlareBungeeSocket.Sockets.SocketHandler.startReading(SocketHandler.java:179)
    11:36:16 [SEVERE]    at me.Markcreator.FlareBungeeSocket.Sockets.SocketHandler.startReading(SocketHandler.java:158)
    11:36:16 [SEVERE]    at me.Markcreator.FlareBungeeSocket.Sockets.SocketHandler.HandleConnection(SocketHandler.java:92)
    11:36:16 [SEVERE]    at me.Markcreator.FlareBungeeSocket.Sockets.SocketHandler.run(SocketHandler.java:295)
     
  9. Offline

    MiniDigger

  10. Ik, but I could give it a try. ;p
     
  11. Offline

    MiniDigger

    Markcreator there is an error in your SocketMessafe constructor. You try to split something which caused the error, not this libary.
     
  12. Code:java
    1. String stream = null;
    2. String dataType = null;
    3. String serverFrom = null;
    4. String serverTo = null;
    5. String info = null;
    6.  
    7. public SocketMessage(String message) {
    8. this.stream = message;
    9. String[] data = message.split(";/");
    10. this.dataType = data[0];
    11. this.serverFrom = data[1];
    12. this.serverTo = data[2];
    13. this.info = data[3];
    14. }
    15.  
    16. public SocketMessage(String datatype, String serverfrom, String serverto, String info) {
    17. this.dataType = datatype;
    18. this.serverFrom = serverfrom;
    19. this.serverTo = serverto;
    20. this.info = info;
    21. this.stream = datatype + ";/" + serverfrom + ";/" + serverto + ";/" + info;
    22. }
    23.  
    24. public String getStream() {
    25. return this.stream;
    26. }
    27.  
    28. public String getDataType() {
    29. return this.dataType;
    30. }
    31.  
    32. public String getServerFrom() {
    33. return this.serverFrom;
    34. }
    35.  
    36. public String getServerTo() {
    37. return this.serverTo;
    38. }
    39.  
    40. public String getInfo() {
    41. return this.info;
    42. }
     
  13. Offline

    MiniDigger

    Markcreator I have not much experience with regex, but the problem is the split method in line 9. Can't realy help you with that (Maybe try to quote it?)
     
  14. Offline

    RawCode

    does not belong to bukkit, there is code sample about client-server communitcation shipped with JDK
     
  15. Offline

    Force_Update1

    Hello,
    MCManager
    why is the SendMessage methode not working ?
     
  16. Offline

    MiniDigger

    Force_Update1
    MCManager was last seen:

    Sep 27, 2012
    Not shure if he will reply...
    And not working isn't one of the kind of bug reports that are helpful.

     
Thread Status:
Not open for further replies.

Share This Page