编写用于发送和接收UDP数据包的服务android

时间:2015-01-17 13:26:37

标签: android sockets

我正在开发一个在本地网络中发送和接收数据的应用。我决定编写一个侦听传入UDP数据包的服务,当收到来自其他设备的数据包时,服务报告通过回调活动来回传传入消息以更新视图。从活动我调用服务上的方法将其发送到所需的目的地。 首先,我想知道,如果我的方法逻辑是正确的,我选择了正确的工具(服务)。 并且在服务上的监听方法存在问题,这是代码。它给出了接收方法的错误:

public class WifiService extends Service {


private final IBinder mBinder = new WifiBinder();
private WifiInterface serviceCallbacks;
public WifiService() {

}

public class WifiBinder extends Binder {
    WifiService getService() {
        // Return this instance of LocalService so clients can call public methods
        return WifiService.this;
    }
}

@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}
public void setCallbacks(WifiInterface callbacks) {
    serviceCallbacks = callbacks;
}
public String Listen_Report() {
    String msg = "";
    try {
        while (true) {
            byte[] IncommingBuffer = new byte[1000];
            InetAddress localaddress = InetAddress.getByName("192.168.43.1");
            DatagramSocket rsc = new DatagramSocket(8008, localaddress);
            DatagramPacket dgp = new DatagramPacket(IncommingBuffer, IncommingBuffer.length);
            rsc.receive(dgp);
            msg = new String(dgp.getData(), 0, dgp.getLength());
            serviceCallbacks.ReportBack(msg);
        }
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (SocketException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return msg;
}
public void Sendmsg(final InetAddress dst, final String msg) throws IOException {
    new Thread(new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {
                byte[] message = msg.getBytes();
                DatagramPacket packet = new DatagramPacket(message, message.length,
                        dst, 8008);
                DatagramSocket dsocket = new DatagramSocket();
                dsocket.send(packet);
                dsocket.close();
            }

            catch (UnknownHostException e) {
                Log.e("Error", e.getMessage());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }).start();

   }
}

这是界面

public interface WifiInterface {
void ReportBack(String msg);
}

这是活动的部分

btnRec.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mService.Listen_Report();

        }
    });
 btnSend.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                mService.Sendmsg(InetAddress.getByName("192.168.43.83"),"From Activity");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });



public void onStart(){
    super.onStart();
    // Bind to LocalService
    Intent intent = new Intent(this, WifiService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

}
protected void onStop() {
    super.onStop();
    // Unbind from the service
    if (mBound) {
        unbindService(mConnection);
        mBound = false;
    }
}
private ServiceConnection mConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName className,
                                   IBinder service) {
        // We've bound to LocalService, cast the IBinder and get LocalService instance
        WifiService.WifiBinder binder = (WifiService.WifiBinder) service;
        mService = binder.getService();
        mBound = true;
        mService.setCallbacks(mainMenu);
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
};


@Override
public void ReportBack(String msg) {
    txtRec.setText(msg);
}

1 个答案:

答案 0 :(得分:0)

好吧,你应该说你收到了哪个错误,但我认为它是一个NetworkOnMainThreadException。

首先,你称之为:

btnRec.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mService.Listen_Report();

    }
});

来自主线程。 即使你使用BroadcastMessages与服务通信(如Ata告诉你的那样),服务也在主线程上运行,因此你会遇到同样的问题。

您必须在另一个线程中运行receive方法,就像使用send方法一样。

public void Receivemsg() throws IOException {
    new Thread(new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
       while (true) {
            byte[] IncommingBuffer = new byte[1000];
            InetAddress localaddress = InetAddress.getByName("192.168.43.1");
            DatagramSocket rsc = new DatagramSocket(8008, localaddress);
            DatagramPacket dgp = new DatagramPacket(IncommingBuffer, IncommingBuffer.length);
            rsc.receive(dgp);
            msg = new String(dgp.getData(), 0, dgp.getLength());
            serviceCallbacks.ReportBack(msg);
        }
    }
    }).start();

   }
}

然后:

public void Listen_Report() 
{
    try 
    {
        Receivemsg();
    } 
    catch (UnknownHostException e)
    {
        e.printStackTrace();
    } 
    catch (SocketException e)
    {
        e.printStackTrace();
    }
    catch (IOException e) 
    {
        e.printStackTrace();
    }
}

最后(因为回调将在主线程之外调用)

@Override
public void ReportBack(String msg) {
    runOnUiThread(new Runnable()
    {
        @Override
        public void run()
        {
            txtRec.setText(msg);
        }
    }

}