0

我正在构建一个实时 GPS 跟踪系统,它将接收从几个使用 UDP 的 Arduino 设备发送的 GPS 数据。到目前为止我有这个代码:

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 - 任何有更多知识的人都可以告诉我是否有更好的方法来做到这一点?我真的不知道 JVM 是如何处理这个问题的,但我不喜欢那个无限循环。

2 - 假设我有 50 个 Arduinos 发送数据。我需要使用线程或类似的东西吗?

3 - 最好为每个“连接”使用一个线程(UDP 是无连接的),就像下面的答案一样,或者使用像 Apache Mina 或 Netty 这样的框架/库?

4

3 回答 3

2

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:

  1. 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));
    }
    
  2. 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;
        }
    }
    
于 2012-08-20T13:39:16.473 回答
1

我建议您查看 Apache MINA (http://mina.apache.org/),这是一个用于网络应用程序的出色框架。使用 MINA,您无需实现循环或担心线程。

于 2012-08-20T12:26:22.533 回答
1

我在您的问题中看到的实际问题是“实时”术语。你那是什么意思?您是否需要一个高度可预测(在时间方面)的应用程序,它是安全/关键任务吗?如果是这样,使用 Java 可能会出现问题,因为它有很多原因(即垃圾收集器等)不是实时的。但是,有一些实时 JVM,例如http://www.atego.com/products/aonix-perc/。我确实喜欢 Java,但我想在这种情况下,如果你真的需要 RT 系统,C++ 会是更好的选择。

于 2012-08-20T12:27:48.687 回答