首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java程序在接收到大约1000个UDP DatagramPackets后冻结10秒,然后再次恢复。

Java程序在接收到大约1000个UDP DatagramPackets后冻结10秒,然后再次恢复。
EN

Stack Overflow用户
提问于 2017-01-11 14:24:41
回答 2查看 400关注 0票数 0

我有一个运行统一C#应用程序的PC,它每隔几毫秒通过网络向其他机器发送一个UDP数据包( windows 7上有两个KUKA机器人,运行相同的JAVA程序,它有一个i5 Intel处理器,所以非常强大)。Java程序应该接收这些包,解析它们的内容(机器人的位置,用由‘#’分隔的7个值组成的数组编码),然后再移动和读取。问题是,当PC以每0.02秒1次的速率发送数据包(这不是在0.03或0.03以上,这是硬件限制?!),java程序会冻结在收到的大约1000个数据包(有时是955或986,等等)。持续8-10秒,然后再继续。当它到达2000年和3000的时候,它也会这样做。

该方案冻结在:

代码语言:javascript
运行
复制
serverSocket.receive(receivedPacket); // receives the array of Bytes

我怀疑网络开关,所以把PC直接连接到机器人上,但没有什么改变。奇怪的是,这两个机器人同时发生,这让我怀疑PC。但是,当我的同事启动一个控制台,实时显示发送数据包的C#程序时,当java程序被冻结时,它并没有冻结,看起来这些数据包丢失了。

我在SO上寻找类似的问题,很多可疑的缓冲区,所以我正在考虑创建一个线程,该线程侦听UDP端口并将数据包存储在内存中的队列中,然后我的主要java程序从该线程读取。这看上去像是一个可行的轨道吗?欢迎任何建议。

这是密码:

代码语言:javascript
运行
复制
package readers;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MyProgram {
    // Network variables 
    public static DatagramSocket serverSocket;
    private static DatagramPacket receivedPacket; 

    // Received data variables
    private static byte[] aReceivedData = new byte[1024];
    private static String sReceivedData;
    private static String sAxesInformationReceived;
    private static Double[] dAxesInformationReceived = new Double[7]; 

    // ******** MAIN ***************************************
    public static void main(String[] args) throws  Exception {  
        int mFramecount =0;
        int mPort = 30004; //default value
        int mTimeout = 20*1000; //default value
        int mFramelimit = (15 * 1000); //default value

        // Create UDP server socket
        try {
            serverSocket = new DatagramSocket(mPort);
            serverSocket.setReuseAddress(true);
            serverSocket.setSoTimeout(mTimeout);
        } catch (SocketException e) 
        {   System.err.println("socket bind fail"); closeSocket();e.printStackTrace(); return; }

        // Receive the UDP packet   
        try {
            receivedPacket = new DatagramPacket(aReceivedData, aReceivedData.length);
            serverSocket.receive(receivedPacket); // receive the array of Bytes
        } catch (Exception e) { closeSocket();  return; }  
        //Clear Buffer  
        for (int i = 0; i < 7; i++) {
            if(dAxesInformationReceived[i] == null)
            {
                dAxesInformationReceived[i] = 0.0;
            }
        }


        // <<<<<<<<<<<WHILE <<<<<<<<<<<<<<<<<<<< 
        while (true) {          

            //Clear Buffer
            for(int i=0; i < aReceivedData.length; i++)
            {
                aReceivedData[i]=0;
            }


            // Decoding and Parsing received values
            try {

                receivedPacket = new DatagramPacket(aReceivedData, aReceivedData.length); 
                serverSocket.receive(receivedPacket); // receive the array of Bytes

                byte[] byteData = new byte[receivedPacket.getLength()];
                System.arraycopy(receivedPacket.getData(), receivedPacket.getOffset(), byteData, 0,  receivedPacket.getLength()); 
                sReceivedData = new String(byteData, "UTF-8");   
                Pattern pattern = Pattern.compile("@(.*?)@"); // RegEx
                Matcher matcher = pattern.matcher(sReceivedData); 
                System.out.println("Data: '" + sReceivedData + "', || length: " + byteData.length + "|| Frame count="+ mFramecount ++);

                /*
                 * mFramecount++;
                        if (mFramecount %100 == 0) {
                            System.out.println("Data: '" + sReceivedData + "', || length: " + byteData.length + "|| Frame count="+ mFramecount );
                        }
                 */

                if (matcher.find()) {
                    sAxesInformationReceived = matcher.group(1);
                    String[] sAxesValuesInStringArray = sAxesInformationReceived.split("#");
                    if (sAxesValuesInStringArray.length != 7) {
                        System.err.println("[UnityControl] invalide number of axis");
                        break;
                    }
                    for (int i = 0; i < 7; i++) {
                        dAxesInformationReceived[i] = Double.parseDouble(sAxesValuesInStringArray[i]);
                    }
                } else {
                    System.err.println("[UnityControl] invalid format");
                    break;
                }
            } catch (Exception e) {
                System.err.println("[UnityControl] socket exception");
                e.printStackTrace();
                break;
            }



            /* THIS PART IS USING THE ROBOT's API */
            // Change destination according to the received position
            JointPosition framePos = new JointPosition(
                    Math.toRadians(dAxesInformationReceived[0]),
                    Math.toRadians(dAxesInformationReceived[1]),
                    Math.toRadians(dAxesInformationReceived[2]),
                    Math.toRadians(dAxesInformationReceived[3]),
                    Math.toRadians(dAxesInformationReceived[4]),
                    Math.toRadians(dAxesInformationReceived[5]),
                    Math.toRadians(dAxesInformationReceived[6]));

            try {
                if(runtime.setDestination(framePos)<0) 
                    break; // break when error planning robot motion
            }
            catch(Exception e)
            {
                System.err.println("Runtime exeption");
                break;
            }

            if(mFramecount >= mFramelimit) break;


        }
        // LOOP BACK  
    }

    //**********************************************************************
    static void closeSocket() {
        if (serverSocket != null) {
            serverSocket.disconnect();
            serverSocket.close();
            System.out.println("[UnityControl] socket closed");

        }
    }

}

我做了@EJP在他的回答中提出的建议,为了更好地跟踪问题,我在它的末尾添加了数据包的数量,看起来这两台机器上的UDP数据包都丢失了(PC的日志显示它没有停止发送)。下面是运行相同代码的两台机器的日志:

EN

Stack Overflow用户

发布于 2017-01-11 16:00:57

很有可能是你的垃圾收集(垃圾收集)的问题,正在制造的东西被称为停止世界。停止这个世界,冻结应用程序,清除未使用对象的内存:)。您可以获得程序PID,然后连接j控制台,查看内存发生了什么变化。

也有可能设置更多的内存将有所帮助。java -Xms1024m -Xmx1024m -Xms设置初始Java堆大小-Xmx设置最大Java堆大小

如果您正在使用许多线程,那么创建线程就有可能是如此的内存和时间消耗--那么您可以使用线程池。

不幸的是,没有任何密码,我无法帮助你更多。

票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41593385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档