Search code examples
javamultithreadingsocketsbukkit

Java, socket, thread


Hello dear StackOverflow users. I come here again to answer a question about Java Socket and Thread. My current code:

new Thread(()->{
             System.out.println("Thread.......");
            try {
                while(true){
                     ServerSocket serverSocket = new ServerSocket(serverPort);
                     Socket socket = serverSocket.accept();
                        final InputStreamReader streamReader = new InputStreamReader(socket.getInputStream());
                        BufferedReader br = new BufferedReader(streamReader);
                        String line = null;
                        while ((line = br.readLine()) != null){
                            JsonObject result = new Gson().fromJson(line, JsonObject.class);
                            String token = result.get("serverToken").getAsString();
                            String player = result.get("player").getAsString();
                            String value = result.get("quantity").getAsString();
                            System.out.println(token+"/"+serverToken);
                            if(token.equals(serverToken)){
                                String command = activeCommand;
                                       command = activeCommand.replace("%value%", value);
                                       command = activeCommand.replace("%player%", player);
                                execCommand(command);
                                System.out.println("Acertou a token!");
                            }else{
                                System.out.println("Token incorreta!");
                            }
                        }
                     serverSocket.close();
                     socket.close();
                     Boolean isClosed = socket.isClosed();
                     System.out.print(isClosed);
                  } 
            } catch (IOException e) {
                System.out.println(e);
            }
        }).start();

It works well, up to a point. After a few requests, it simply gives the error: java.net.BindException: Address already in use (Bind failed)

I've been looking for some time, but I haven't found a solution. Thanks in advance.


Solution

  • I don't have a definitive answer but what I do have is some possible problems and some improvements.

    1. You're not closing some Closeable resources.
    2. An exception may be thrown and not caught in this thread.

    Improvements

    1. 4 Closeable objects all put into multiple try-with-resources.
    2. You're now using a ThreadFactory that prints all uncaught exceptions.
    3. You're now printing the IOException, if one occurs.
    4. You're now using a ExecutorService that uses the ThreadFactory.
            ThreadFactory threadFactory = new ThreadFactoryBuilder()
                    .setUncaughtExceptionHandler((thread, throwable) -> throwable.printStackTrace())
                    .setNameFormat("my-server-thread")
                    .build();
    
            ExecutorService service = Executors.newSingleThreadScheduledExecutor(threadFactory);
    
            service.submit(() -> {
                while(true) {
                    try (ServerSocket serverSocket = new ServerSocket(port)) {
                        try (Socket socket = serverSocket.accept()) {
                            try (InputStreamReader streamReader = new InputStreamReader(socket.getInputStream());
                                 BufferedReader br = new BufferedReader(streamReader)) {
                                String line;
    
                                while ((line = br.readLine()) != null) {
                                    // your other code in here
                                }
                            }
                        }
                    } catch (IOException ioe) {
                        ioe.printStackTrace();
                    }
                }
            });