Reputation: 3341
I'm building a real-time GPS tracking system, which will receive GPS data sent from a couple of Arduino devices using UDP. I have this code so far:
PreparedStatement stmt ...
DatagramSocket serverSocket = new DatagramSocket(9876);
byte[] receiveData = new byte[1024];
while(true){
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String received = new String( receivePacket.getData());
System.out.println("RECEIVED: " + received);
stmt.set...
stmt.execute();
}
1 - Anyone with more knowledge could tell me if there's a better way of doing this? I really don't know how the JVM handles this, but I don't like that infinite loop.
2 - Lets say that I have 50 Arduinos sending data. I need to use threads or something like this?
3 - It's best to use a thread per "connection" (UDP is connectionless) like an answer below or use frameworks/libs like Apache Mina or Netty?
Upvotes: 0
Views: 2840
Reputation: 63359
There is no problem using an infinite loop in this case. Calling receive waits until a new datagram is delivered:
This method blocks until a datagram is received. T...
So no CPU power is wasted here, it simply waits until new data is available.
If you have many clients or if processing the packet isn't completely trivial, you should start a new thread for processing each one, so that the main thread that receives the datagrams doesn't get blocked. Probably the best approach is to use thread pools that will create threads for you, and at the same time prevent creating too many threads if your application is overloaded by requests.
I'd proceed as follows:
Create a dedicated thread for receiving the datagrams. It could also create a thread pool for dispatching processing the requests. Something like:
int maxNumberOfThreads = ...; // your choice
int bufSize = ...; // your choice
ExecutorService exec = Executors.newFixedThreadPool(maxNumberOfThreads);
DatagramSocket serverSocket = new DatagramSocket(9876);
while (true) {
// we need to create a new buffer every time because
// multiple threads will be working with the data
DatagramPacket receivePacket =
new DatagramPacket(new byte[bufSize], bufSize);
serverSocket.receive(receivePacket);
exec.submit(new YourTask(receivePacket));
}
Create class YourTask
that processes the datagrams:
// We don't use return values for anything here, so
// we just use Object.
public class YourTask extends Callable<Object> {
private DatagramPacket received;
public YourTask(DatagramPacket received) {
this.received = received;
}
public Object call() {
// do your processing here
System.out.println("RECEIVED from " +
received.getAddress() +
": " + new String(received.getData(),
0, received.getLength()));
return null;
}
}
Upvotes: 2
Reputation: 7440
The actual problem I see in your question is the "Real Time" term. What do you mean with that? Do you need a highly predictable (in terms of timing) application, is it safety/mission critical? If so there may be problem in using Java, as it is for many reasons (i.e. garbage collector, etc.) not realtime. There are however some realtime JVM as http://www.atego.com/products/aonix-perc/. I do like Java but I guess in this case, if you really need a RT system, C++ would be a better choice.
Upvotes: 1
Reputation: 458
I recommend you look at Apache MINA (http://mina.apache.org/), a great framework for network applications. With MINA you don't need to implement a loop or worry about threading.
Upvotes: 1