/* Copyright 2013 RobustNet Lab, University of Michigan. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.udpmeasurement; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; /** * @author Hongyi Yao (hyyao@umich.edu) * The thread sends data to the client according to the downlink request packet * Therefore, the downlink burst will not block the processing of other uplink * data packet */ public class RequestHandler implements Runnable { private DatagramSocket socket; private ClientIdentifier clientId; private ClientRecord clientRecord; /** * Constructor * @param socket the datagram socket created by the receiver thread * @param clientId corresponding client identifier * @param clientRecord the downlink request */ public RequestHandler(DatagramSocket socket, ClientIdentifier clientId, ClientRecord clientRecord) { this.socket = socket; this.clientId = clientId; this.clientRecord = clientRecord; } /** * Send a downlink packet according to ClientRecord * @throws MeasurementError send failed */ private void sendPacket(MeasurementPacket packet, int packetNum) throws MeasurementError { packet.packetNum = packetNum; packet.timestamp = System.currentTimeMillis(); byte[] sendBuffer = packet.getByteArray(); DatagramPacket sendPacket = new DatagramPacket( sendBuffer, sendBuffer.length, clientId.addr, clientId.port); try { socket.send(sendPacket); } catch (IOException e) { throw new MeasurementError( "Fail to send UDP packet to " + clientId.toString()); } Config.logmsg("Sent response to " + clientId.toString() + " type: PKT_DATA b:" + packet.burstCount + " p:" + packet.packetNum + " timestamp:" + packet.timestamp + " s:" + packet.packetSize + " seq:" + packet.seq); } /* (non-Javadoc) * @see java.lang.Runnable#run() * send n=burstCount downlink packets with the interval of udpInterval */ @Override public void run() { MeasurementPacket dataPacket = new MeasurementPacket(clientId); dataPacket.type = Config.PKT_DATA; dataPacket.burstCount = clientRecord.burstCount; dataPacket.packetSize = clientRecord.packetSize; dataPacket.seq = clientRecord.seq; for ( int i = 0; i < clientRecord.burstCount; i++ ) { try { sendPacket(dataPacket, i); } catch (MeasurementError e) { Config.logmsg("Error processing message: " + e.getMessage()); break; } try { Thread.sleep(clientRecord.udpInterval); } catch (InterruptedException e) { Config.logmsg("sleep is interrupted: " + e.getMessage()); } } } }