我遇到了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调用一次。可能是滞后的原因是什么?