使用AsyncTask发送UDP数据包

时间:2014-11-12 21:41:02

标签: java android android-asynctask udp

我正在尝试将UDP数据包发送到与平板电脑位于同一网络的计算机上。为了做到这一点,我开始设置一个类来保存我需要的所有适当的对象,以便创建UDP套接字,创建数据包,然后发送该数据包。该课程如下所示:

public static class Session
    {
        public InetAddress address;
        public DatagramSocket socket;
        public DatagramPacket packet;
        public String client;
        public int port;
        public byte[] receive_buffer;
        public byte[] send_buffer;
        public String message;

        public Session (InetAddress address, DatagramSocket socket, DatagramPacket packet,
                        String client, int port, byte[] receive_buffer, byte[] send_buffer,
                        String message)
        {
            this.address = address;
            this.socket = socket;
            this.packet = packet;
            this.client = client;
            this.receive_buffer = receive_buffer;
            this.send_buffer = send_buffer;
            this.message = message;
            this.port = port;
        }
    }

每当我尝试发送UDP数据包时,我首先创建一个包含套接字,数据包,消息和其他一些东西的Session对象。我还有一个Send类用于实际发送UDP数据包。如下所示:

public static Session Send (Session session)
    {
        // Execute within "try" function to catch exceptions
        try
        {
            /* Create address*/
            session.address = InetAddress.getByName(session.client);
            /* Create socket */
            session.socket = new DatagramSocket(session.port);
            /* Create packet */
            session.packet = new DatagramPacket(session.message.getBytes(),
                                 session.message.length(), session.address, session.port);
            /* Send packet */
            session.socket.send(session.packet);
            /* Return session */
            return session;
        }
        catch (Exception e)
        {
            Log.e("MYAPP", "exception: " + e.getMessage());
            Log.e("MYAPP", "exception: " + e.toString());
        }
        return null;
    }

但是,无法直接调用Send(),因为无法在UI线程上执行网络操作。为了解决这个问题,我创建了一个调用Send()的AsyncTask。现在我所要做的就是将Session对象传递给AsyncTask,它将发送数据包(理论上)。我创建的AsyncTask如下所示:

class sendData extends AsyncTask<UDP.Session, Void, UDP.Session>
    {

        /* Pre-Execute Function */
        @Override
        protected void onPreExecute ()
        {
            super.onPreExecute();
        }

        /* Main AsyncTask Function */
        @Override
        protected UDP.Session doInBackground(UDP.Session... arguments)
        {
            /* Send UDP packet */
            UDP.Session session = UDP.Send(arguments[0]);
            return session;
        }

        /* Post-Execute Function */
        @Override
        protected void onPostExecute (UDP.Session session)
        {
            super.onPostExecute(session);
        }
    }

我遇到的问题是我无法弄清楚如何从AsyncTask返回会话对象。关键是我返回传递给AsyncTask的会话,因为否则套接字/端口会损坏,当我尝试发送另一个数据包时,我会遇到绑定异常和一大堆其他问题。我尝试使用:

UDP.Session nsession = new sendData().execute(ssession).get(); 

但是我收到一条错误,指出“未处理的异常:java.lang.InterruptedException,java.util.concurrent.ExecutionException”。所以我的问题是什么是最好的方式让我返回传递给AsyncTask的会话对象,以便下次我想发送数据包时可以使用相同的会话对象。

1 个答案:

答案 0 :(得分:1)

我很傻,没注意编译器有关未处理异常的警告。上面提到的AsyncTask调用(UDP.Session nsession = new sendData().execute(ssession).get();)确实是正确的,但它只需要放在try / catch语句中捕获任何可能的异常。当我将代码更改为以下内容时......

try{
    session = new sendData().execute(session).get();}
catch (Exception exception){}

......一切正常。我能够从AsyncTask正确返回一个对象,并且当AsyncTask完成时我的套接字不再被破坏,允许我发送尽可能多的数据包