udp传输中的Android延迟

时间:2014-05-18 15:22:29

标签: java android network-programming udp android-networking

我遇到了udp传输滞后的问题(通过本地wifi网络)。主机使用50Hz的UdpSender将数据发送到所有客户端:

UDPSender:

public class UDPSender {

    private DatagramSocket socket;

    private DatagramPacket packet;

    private ByteBuffer bb;

    private InetAddress targetAddress;

    private byte[] bytearray;

    public UDPSender(int port,String targetAddress){
        try {
            this.targetAddress =  InetAddress.getByName(targetAddress);
        } catch (UnknownHostException e) {
        }
        try {
            socket = new DatagramSocket();
        } catch (IOException e) {
        }
        bb = ByteBuffer.allocate(169);
        bytearray = bb.array();
        packet = new DatagramPacket(bytearray, bytearray.length, this.targetAddress, port);
    }


    public void sendSignal(/*args*/){
        if(!socket.isClosed()){
            bb.putInt(pos, ...)   //fill 'bb' with data from args
                    ...
            bytearray = bb.array();
            packet.setData(bytearray);
            try {
                socket.send(packet);
            } catch (IOException e) {
            }
        }   
    }
    public void close(){
        socket.close();
    }

}

UDPReceiver:

public class UDPReceiver {

    private DatagramSocket socket;

    private DatagramPacket packet;

    private byte[] packetDataBuffer = new byte[169];

    private UDPSignalListener listener = null;

    private ByteBuffer bb;

    private String hostAddress;

    private boolean isOpen = false;

    private byte buffer;

    private short bytes;

    public UDPReceiver(int port, String hostAddress, UDPSignalListener listener){
        try {
            socket = new DatagramSocket(port);
        } catch (IOException e) {
            if(listener!=null)
                listener.errorOpeningSocket(port);
        }
        packet = new DatagramPacket(packetDataBuffer, packetDataBuffer.length);
        this.hostAddress = hostAddress;
        this.listener = listener;
        isOpen = true;
        Thread t = new Thread(new Runnable(){

            @Override
            public void run() {
                listen();
            }

        });
        t.setDaemon(true);
        t.start();

    }

    public void start(String hostAddress){
        this.hostAddress = hostAddress;
        isOpen = true;
        Thread t = new Thread(new Runnable(){

            @Override
            public void run() {
                listen();
            }

        });
        t.setDaemon(true);
        t.start();
    }

    private void listen(){
        while(isOpen){
            try {
                socket.receive(packet);
            } catch (IOException e) {
                continue;
            }
            if(!isOpen)
                return;
            if(packet.getAddress().getHostAddress().equals(hostAddress)){
                bb = ByteBuffer.wrap(packetDataBuffer);
                //read data from bb
                if(listener!=null)
                    listener.onSignalRecieved(/*pass data to program*/);
            }    
        }
    }

    public int getPort(){
        return socket.getLocalPort();
    }
    public void close(){
        isOpen = false;
        socket.close();
    }

}

主机端的MainThread:

mainThread = new Thread(new Runnable(){
        public void run(){
            while(isMainLoopRunning){ 
                ...
                for(int i=0;i<udpSender.length/*max 5*/;++i)
                    udpSender[i].sendSignal(...);  //~50fps constantly //send data to client i
                ...
            }
        }
});

客户端通过UDPSignalListener.onSignalReceived()获取数据(应该每隔20ms(50fps)调用一次)。数据被保存并用于客户端的mainThread(也经常以50fps运行)。不幸的是,有时会出现滞后(延迟达1秒),即onSignalReceived不会每20ms调用一次。可能是滞后的原因是什么?

0 个答案:

没有答案