2012-08-16 317 views
0

我正在构建一个实时GPS跟踪系统,它将接收使用UDP从几个Arduino设备发送的GPS数据。我有这个代码到目前为止:通过UDP接收实时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这样的框架/库?

回答

2

在这种情况下使用无限循环没有问题。调用receive等待直到发送新的数据报:

该方法阻塞直到收到数据报。 T ...

因此,这里没有CPU功率浪费,它只是等待,直到有新数据可用。

如果你有很多客户端,或者如果处理数据包不是很平凡,你应该启动一个新的线程来处理每一个线程,以便接收数据报的主线程不会被阻塞。可能最好的方法是使用thread pools为您创建线程,并且同时防止在应用程序被请求过载时创建太多线程。

我会进行如下操作:

  1. 用于接收数据报创建一个专门的线程。它也可以创建一个线程池来调度处理请求。喜欢的东西:

    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. 创建YourTask类处理数据报:

    // 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; 
        } 
    } 
    
+0

感谢您的答案。你知道什么性能最好:你的代码是线程还是基于NIO的,比如Apache Mina或Netty?我正在谈论50个或更多的连接开始。这个代码与千位连接的行为是什么? – fonini 2012-08-20 16:17:50

+0

@fonini我会说NIO有更好的表现(这是他们做这件事的原因之一)。但是我认为NIO对于TCP来说更重要,因为您需要管理状态连接。 IIUC你只有无状态的数据报,所以这使得事情更简单,没有NIO。恕我直言,这里的问题是:(1)你想/你可以使用多个CPU吗? (2)处理个别请求需要更长的时间吗?如果是,那么我会使用线程进行处理,无论您是否使用NIO。 – 2012-08-20 19:44:50

1

我建议你看看Apache MINA(http://mina.apache.org/),这是一个很好的网络应用程序框架。使用MINA,您不需要执行循环或担心线程。

+0

或网状的选项(https://netty.io/) – whiter4bbit 2012-08-20 12:27:59

+0

什么用的Apache Tomcat的效果最好?或者有一个比Tomcat轻量级的服务器? – fonini 2012-08-20 13:00:47

+0

我正在使用Mina与Java SE应用程序,不知道它与Tomcat有多么好或坏... – 2012-08-20 13:06:48

1

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