How to listen to / wait for TCP packets

Hey guys,
I need a TCP connection between my PHP Website and my Java plugin.
I think nobody asked this before, so here is an example:

A player changes a setting in his control panel (website). Then PHP will send for example a JSON array / object to localhost:8123.
My plugin should listen on this port. As soon as it gets the JSON data, it should print it (console).

So I never did something like that before, I just looked around for solutions, but unfortunately I could not find a good example / solution.

Here is my Java code:

import java.io.*;
import java.net.*;
/**
 * Created by pucks on 04.12.15.
 */
public class tcp {


public static void main(String argv[]) throws Exception {
    String clientSentence;
    String capitalizedSentence;
    ServerSocket welcomeSocket = new ServerSocket(8123);

    while (true) {
        Socket connectionSocket = welcomeSocket.accept();
        BufferedReader inFromClient =
                new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
        DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
        clientSentence = inFromClient.readLine();
        System.out.println("Received: " + clientSentence);
        capitalizedSentence = clientSentence.toUpperCase() + '\n';
        outToClient.writeBytes(capitalizedSentence);
        connectionSocket.close();
    }
}

}

So I created an object onServerStart → tcp tcp = new tcp().
When I send a TCP request, it seems like there is no service waiting for it … → no effect

My questions:

  1. How do I have to modify my code to get it working?
  2. How can I start the TCP listener then and print the received (JSON) data?

Thanks for helping me,
Greets :slight_smile:

Calling new tcp() is different from calling tcp.main(). main() is only used when you are creating a standalone program. Change the line public static void main(String[] args) { to public tcp() { to have the code run when you say new tcp().

1 Like

Also, 8123 might interfear with dynmap

1 Like

I know, I know, but this is just an example :smile:

First, to make sure you receive everything from the php website, you need to do that:

String line;

while((line = inFromClient.readLine()) != null)
    clientSentence += line;
1 Like

Sorry for not responding …
I found a solution, but there is a problem!

public class tcp {
	String clientSentence;

	public tcp () throws IOException {

		String capitalizedSentence;
		ServerSocket welcomeSocket = new ServerSocket(25533);
		System.out.println("lel wurde eingerichtet");

		String line;
		Socket connectionSocket = welcomeSocket.accept();
		BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
	
		while((line = inFromClient.readLine()) != null) {
			clientSentence += line;
		}

		System.out.println(clientSentence);
	} 
}

Btw: thanks to @JBYoshi for advise, I did this in the past, but forgot to throw an IOException :slight_smile: But adding the code to the constructor of tcp works fine ^^.

So the tcp service works, but when I start my listener by writing tcp tcp = new tcp() in onServerStart(), it seems like my server freezes. I can print received data, but as I said, my forge server is “freezed”. So I think, I have to start my TCP listener in background or something similar…

Please can you guys say me, how I can do that?
Thanks

You need to run your TCP server on an another thread because the TCP server will stop the thread until a new connection.

1 Like

Thanks dude!
Don’t know, if this is good practice, but it works when I do it like this:

Thread t1 = new Thread(new Runnable() {
    public void run() {
        try {
            tcp tcp = new tcp();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
});
t1.start();

This is good, but that will handle only one connection.

1 Like

Hmm, okay, how can I build a code, that can handle multiple connections?

You can change the true for any value you want, and to stop your thread when the server stop you have to do ss.close();

final ServerSocket ss = new ServerSocket();
Thread t1 = new Thread(new Runnable() {
    public void run() {
        try {
            while(true)
              Tcp tcp = new Tcp(ss.accept());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});
t1.start();
1 Like

Ok, something is wrong with my code.

I added your sample -> error: socket is not bound -> I added ss.bind(new InetSocketAddress("127.0.0.1", 0)); in main -> error does not occur, but my tcp threads do not start…

Main:

final ServerSocket ss = new ServerSocket();
ss.bind(new InetSocketAddress("127.0.0.1", 0));
Thread t1 = new Thread(new Runnable() {
    public void run() {
        try {
            while(true) {
                tcp tcp = new tcp(ss.accept(), logger);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});
t1.start();

tcp object:

import org.slf4j.Logger;
import java.io.*;
import java.net.*;

public class tcp {
	private String clientSentence;
	private String line;

	public tcp (Socket ss, Logger logger) throws IOException {

		String capitalizedSentence;
		ServerSocket welcomeSocket = new ServerSocket(25533);

		Socket connectionSocket = welcomeSocket.accept();
		BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
		while((line = inFromClient.readLine()) != null) {
			clientSentence += line;
		}

		logger.info(clientSentence);

	}
}

So I think, that there should be a connection or something like that…
Thanks…

Change your port.

1 Like

that does not work. I do not understand why it should… when I use this in my main:

Thread t1 = new Thread(new Runnable() {
    public void run() {
        try {
            tcp tcp = new tcp(logger);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
});
t1.start();

and following code in my tcp object:

import org.slf4j.Logger;

import java.io.*;
import java.net.*;

public class tcp {
private String clientSentence;
private String line;

public tcp (Logger logger) throws IOException {

	String capitalizedSentence;
	ServerSocket welcomeSocket = new ServerSocket(25533);

	Socket connectionSocket = welcomeSocket.accept();
	BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
	while((line = inFromClient.readLine()) != null) {
		clientSentence += line;
	}

	logger.info(clientSentence);

}

}

I can receive a packet, but only one. After I received one it’s like I shut down my server…

EDIT:

IM SO SORRY :smile: I saw that I tried to use port 0…

I changed it also to port 25533 and I can connect to my plugin with php.

BUT

I get following error when I try (I do not understand why…)

[15:43:36] [Thread-7/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: java.net.BindException: Address already in use
[15:43:36] [Thread-7/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at java.net.PlainSocketImpl.socketBind(Native Method)
[15:43:36] [Thread-7/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
[15:43:36] [Thread-7/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at java.net.ServerSocket.bind(ServerSocket.java:375)
[15:43:36] [Thread-7/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at java.net.ServerSocket.(ServerSocket.java:237)
[15:43:36] [Thread-7/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at java.net.ServerSocket.(ServerSocket.java:128)
[15:43:36] [Thread-7/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at me.Hitzk0pf.CaveCore.tcp.(tcp.java:17)
[15:43:36] [Thread-7/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at me.Hitzk0pf.CaveCore.Main$3.run(Main.java:242)
[15:43:36] [Thread-7/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at java.lang.Thread.run(Thread.java:745)

Try this

final ServerSocket ss = new ServerSocket(25533);
Thread t1 = new Thread(new Runnable() {
    public void run() {
        try {
            while(true) {
                tcp tcp = new tcp(ss.accept(), logger);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});
t1.start();

import org.slf4j.Logger;
import java.io.*;
import java.net.*;

public class tcp {
	private String clientSentence;
	private String line;

	public tcp (Socket connectionSocket , Logger logger) throws IOException {
		String capitalizedSentence;
		BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
		while((line = inFromClient.readLine()) != null) {
			clientSentence += line;
		}

		logger.info(clientSentence);

	}
}
1 Like

thank you so much :smile:

1 Like