jmonkey和netbeans之间的连接

时间:2013-12-11 09:32:05

标签: java sockets netbeans jmonkeyengine

我正在为学校做一个项目。我们正在建造一个可以装卸船只的港口。控件部分在Netbeans中进行,模拟在JME中。 我们通过套接字将数据从Netbeans发送到JME。 JME正在运行一个来自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;
        }
    }
}

Main 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);
    }
}

1 个答案:

答案 0 :(得分:0)

您的计划存在许多问题。

首先 - 你有潜在的竞争和线程争用问题,因为你有“计数”,我假设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()删除所有现有代码。

Callableenqueue将在下次更新时从JME3线程回调,并处理容器的添加。通过为每个不同的命令执行类似的操作,它将enqueue并随着时间的推移处理所有命令。您可以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

P.S。您应该尝试遵循Java样式/编码约定 - 例如,方法应该以小写开头。 initContainers不是InitContainers。