2013-12-11 83 views
0

我正在爲學校開展一個項目。我們正在建造一個可以裝載和卸載船隻的港口。控制部分在NetbeansJME模擬。 我們通過套接字將數據從Netbeans發送到JME。 JME正在運行一個服務器端口,接受Netbeans的輸入。jmonkey和netbeans之間的連接

例如Netbeans發送一個容器的ID,並在JME的起重機獲取該容器並將其放在岸上,以便車輛可以拿起它。

我們更改主計數(Main.count = 2),因此SimpleUpdate可以調用方法。問題是有時候東西會被跳過。另外我認爲,當我們發送更多信息,例如獲取容器的車輛時,情況會變得更糟。我怎樣才能解決這個問題?還有其他方法可以獲得良好的聯繫嗎?

代碼:

Netbeans的

發送端

public static void run() throws Exception 
{  
    Socket socket = new Socket("Localhost", 4321);  
    out = new ObjectOutputStream(socket.getOutputStream());  
} 

//Sent arraystring to Simulation 
public void sent(String sentString){ 
    try { 
     out.writeObject(sentString); 
    } catch (IOException ex) { 
     Logger.getLogger(CommunicationWithSimulatoin.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

主送些東西,例如

for(int i = Calculator.getContainersFromMaritime(); i > 1; i--) 
{ 
    Thread.sleep(50); 
    sim.sent("craneCon;" + i + ";"); 
    System.out.println(i);    
} 

JME

監聽

public static void Listener() throws Exception { 
    boolean isRunning = true; 
    //Creates the server socket 
    ServerSocket sSocket = new ServerSocket(4321); 
    //Acception a connection from the client 

    Socket socket = sSocket.accept(); 
    ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); 
    //Get the input from the client 

    while (isRunning) { 
     //Reads and prints the input 
     test = (String) in.readObject(); 
     System.out.println(test); 
     String[] parts = receivedString.split(";"); 

     if(parts[0].equals("ContainerPositionsMaritime")) 
     { 
      Maritime.ContainersOnBoard = receivedString.split(";"); 
      Main.count = 0; 
     } 
     if(parts[0].equals("craneCon")) 
     { 
      int containerId = Integer.parseInt(parts[1]); 
      SeagoingCranes.idContainer = containerId; 
      Main.count = 2; 
     } 
    } 
} 

主要simpleupdate

public void simpleUpdate(float tpf) { 
    if(count == 0) 
    { 
     InitContainers(); 
     //martime.setLocalTranslation(0, 500.0f, 0); 
     count = 999; 
    } 
    if(count == 2) 
    { 
     InitCrane(SeagoingCranes.idContainer); 
     count = 999; 
    } 
    if(martime != null) 
    { 
     martime.move(0,0,0.25f*tpf); 
    } 
} 
+0

netbeans中的控件是什麼意思?你的意思是你在netbeans中運行一個簡單的應用程序? –

+0

控制系統的意思是發送JME零件必須做的事情,比如拿到那個容器或者把那輛車送到那個地方拿起那個容器。 –

+0

我無法回答這個問題,但請注意netbeans只是一個IDE,它不是您的程序的一部分;這是你寫你的程序與 –

回答

0

有許多與你的程序的問題。

首先 - 您有潛在的競爭和線程爭用問題,因爲您有「count」,我認爲這是一個整數值,其中SimpleApplication正在從一個線程修改並從另一個線程讀取。除非該值被聲明爲volatile,否則可能會導致各種意想不到的問題和奇怪的行爲,甚至不建議將其聲明爲volatile。

雖然你的主要問題(甚至不考慮細微的問題)是由於simpleUpdate()你正在掃描計數然後根據計數採取行動而引起的。當您的jME3應用程序正在運行時,每幀會調用一次simpleUpdate()

如果您在一個框架中收到多條消息,那麼只有最後一條消息會被執行,因爲在下一個simpleUpdate()運行之前計數將再次被修改。

做到這一點的最好方法是使用app.enqueue()

 if(parts[0].equals("ContainerPositionsMaritime")) 
     { 
      final ContainersOnBoard containers = receivedString.split(";"); 
      mainApp.enqueue(new Callable<Spatial>() { 
       public Spatial call() throws Exception { 
        mainApp.InitContainers(containers); 
        return null; 
       } 
      });     
      } 

     } 

您可以從您的simpleUpdate()中刪除所有現有的代碼。

Callable you enqueue將在下次更新時從JME3線程回調並處理添加的容器。通過爲每個不同的命令做類似的事情,它會隨着時間的推移而處理所有的命令。你可以使用enqueue儘可能多的命令,他們都將被處理。

一般來說,您應該閱讀AppStates,Controls和線程模型,因爲它們可以使您的代碼更加結構化和組織化。

http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:multithreading

http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:application_states

http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:custom_controls

附:您應該嘗試遵循Java風格/編碼慣例 - 例如方法應該以小寫字母開頭。 initContainers不是InitContainers。

+0

感謝您的回覆!我會努力:)。我通常使用小寫字母,但我在一個小組中工作,並不是每個人都使用它。 –