From efa57d7516407541932f044d09e6977288c6b5e5 Mon Sep 17 00:00:00 2001 From: Quentin De Coninck Date: Thu, 23 Feb 2017 17:01:23 +0100 Subject: [PATCH] siri: updated xp to add delay between bursts of requests --- src/SiriClient.java | 44 ++++++++++++++++++++++++------------ src/mpExperienceSiri.py | 4 +++- src/mpExperienceSiriHTTP.py | 4 +++- src/mpExperienceSiriMsg.py | 4 +++- src/mpParamXp.py | 4 ++++ src/siriClient.jar | Bin 14079 -> 14350 bytes 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/SiriClient.java b/src/SiriClient.java index 366cf1d..07b748b 100644 --- a/src/SiriClient.java +++ b/src/SiriClient.java @@ -13,7 +13,7 @@ import java.util.Collections; public class SiriClient { private String serverMessage; - + /* Client parameters */ public final String SERVERIP; //your computer IP address public final int SERVERPORT; @@ -25,7 +25,9 @@ public class SiriClient { public final int MAX_PAYLOAD_SIZE; public final int INTERVAL_TIME_MS; public final int BUFFER_SIZE; - + public final int BURST_SIZE; + public final int INTERVAL_BURST_TIME_MS; + private boolean mRun = false; private int messageId = 0; private static final int MAX_ID = 100; @@ -41,18 +43,20 @@ public class SiriClient { OutputStream outputStream; OutputStreamWriter osw; Socket socket; + private int pktCounter; /** * Constructor of the class. OnMessagedReceived listens for the messages received from server */ public SiriClient(String serverIp, int serverPort, int runTime, int querySize, int responseSize, int delayQueryResponse, int minPayloadSize, int maxPayloadSize, int intervalTimeMs, - int bufferSize) { + int bufferSize, int burstSize, int intervalBurstTimeMs) { random = new Random(); sentTime = new long[MAX_ID]; delayTime = new ArrayList<>(); counter = 0; missed = 0; + pktCounter = 0; /* Client parameters */ SERVERIP = serverIp; SERVERPORT = serverPort; @@ -64,10 +68,12 @@ public class SiriClient { MAX_PAYLOAD_SIZE = maxPayloadSize; INTERVAL_TIME_MS = intervalTimeMs; BUFFER_SIZE = bufferSize; + BURST_SIZE = burstSize; + INTERVAL_BURST_TIME_MS = intervalBurstTimeMs; } - + public SiriClient(String serverIp, int serverPort, int runTime) { - this(serverIp, serverPort, runTime, 2500, 750, 0, 85, 500, 333, 9); + this(serverIp, serverPort, runTime, 2500, 750, 0, 85, 500, 333, 9, 0, 0); } protected String getStringWithLengthAndFilledWithCharacter(int length, char charToFill) { @@ -257,11 +263,17 @@ public class SiriClient { final long startTime = System.currentTimeMillis(); while (socket != null && !socket.isClosed()) { try { - Thread.sleep(INTERVAL_TIME_MS); //* getPoisson(3)); + if (BURST_SIZE > 0 && pktCounter == BURST_SIZE) { + Thread.sleep(INTERVAL_BURST_TIME_MS); + pktCounter = 0; + } else { + Thread.sleep(INTERVAL_TIME_MS); //* getPoisson(3)); + } if ((System.currentTimeMillis() - startTime) >= RUN_TIME * 1000) { stopClient(); } else if (!socket.isClosed() && counter <= QUERY_SIZE * BUFFER_SIZE) { sendMessage(); + pktCounter++; } else if (!socket.isClosed()) { missed++; } @@ -325,14 +337,14 @@ public class SiriClient { } } - + public static void usage() { System.out.println("Usage: siriClient serverIP serverPort runTime [querySize responseSize delayQueryResponse " - + "minPayloadSize maxPayloadSize intervalTimeMs bufferSize]"); + + "minPayloadSize maxPayloadSize intervalTimeMs bufferSize burstSize intervalBurstTimeMs]"); } - + public static void main(String[] args) { - if (args.length != 3 && args.length != 10) { + if (args.length != 3 && args.length != 12) { usage(); System.exit(1); } @@ -340,8 +352,8 @@ public class SiriClient { int serverPort = Integer.parseInt(args[1]); int runTime = Integer.parseInt(args[2]); SiriClient siriClient; - - if (args.length == 10) { + + if (args.length == 12) { int querySize = Integer.parseInt(args[3]); int responseSize = Integer.parseInt(args[4]); int delayQueryResponse = Integer.parseInt(args[5]); @@ -349,12 +361,14 @@ public class SiriClient { int maxPayloadSize = Integer.parseInt(args[7]); int intervalTimeMs = Integer.parseInt(args[8]); int bufferSize = Integer.parseInt(args[9]); + int burstSize = Integer.parseInt(args[10]); + int intervalBurstTimeMs = Integer.parseInt(args[11]); siriClient = new SiriClient(serverIp, serverPort, runTime, querySize, responseSize, delayQueryResponse, - minPayloadSize, maxPayloadSize, intervalTimeMs, bufferSize); + minPayloadSize, maxPayloadSize, intervalTimeMs, bufferSize, burstSize, intervalBurstTimeMs); } else { siriClient = new SiriClient(serverIp, serverPort, runTime); } - + String mac = "00:00:00:00:00:00"; siriClient.run(mac); System.out.println("missed: " + siriClient.missed); @@ -362,4 +376,4 @@ public class SiriClient { System.out.println(delay); } } -} \ No newline at end of file +} diff --git a/src/mpExperienceSiri.py b/src/mpExperienceSiri.py index 927a704..78918b3 100644 --- a/src/mpExperienceSiri.py +++ b/src/mpExperienceSiri.py @@ -43,6 +43,8 @@ class MpExperienceSiri(MpExperience): self.max_payload_size = self.xpParam.getParam(MpParamXp.SIRIMAXPAYLOADSIZE) self.interval_time_ms = self.xpParam.getParam(MpParamXp.SIRIINTERVALTIMEMS) self.buffer_size = self.xpParam.getParam(MpParamXp.SIRIBUFFERSIZE) + self.burst_size = self.xpParam.getParam(MpParamXp.SIRIBURSTSIZE) + self.interval_burst_time_ms = self.xpParam.getParam(MpParamXp.SIRIINTERVALBURSTTIMEMS) def prepare(self): MpExperience.prepare(self) @@ -61,7 +63,7 @@ class MpExperienceSiri(MpExperience): s = MpExperienceSiri.JAVA_BIN + " -jar " + os.path.dirname(os.path.abspath(__file__)) + "/siriClient.jar " + \ self.mpConfig.getServerIP() + " 8080 " + self.run_time + " " + self.query_size + " " + self.response_size + \ " " + self.delay_query_response + " " + self.min_payload_size + " " + \ - self.max_payload_size + " " + self.interval_time_ms + " " + self.buffer_size + \ + self.max_payload_size + " " + self.interval_time_ms + " " + self.buffer_size + " " + self.burst_size + " " + self.interval_burst_time_ms + \ " >" + MpExperienceSiri.CLIENT_LOG + " 2>" + MpExperienceSiri.CLIENT_ERR print(s) return s diff --git a/src/mpExperienceSiriHTTP.py b/src/mpExperienceSiriHTTP.py index 3602836..2315866 100644 --- a/src/mpExperienceSiriHTTP.py +++ b/src/mpExperienceSiriHTTP.py @@ -46,6 +46,8 @@ class MpExperienceSiriHTTP(MpExperience): self.max_payload_size = self.xpParam.getParam(MpParamXp.SIRIMAXPAYLOADSIZE) self.interval_time_ms = self.xpParam.getParam(MpParamXp.SIRIINTERVALTIMEMS) self.buffer_size = self.xpParam.getParam(MpParamXp.SIRIBUFFERSIZE) + self.burst_size = self.xpParam.getParam(MpParamXp.SIRIBURSTSIZE) + self.interval_burst_time_ms = self.xpParam.getParam(MpParamXp.SIRIINTERVALBURSTTIMEMS) self.file = self.xpParam.getParam(MpParamXp.HTTPFILE) self.random_size = self.xpParam.getParam(MpParamXp.HTTPRANDOMSIZE) @@ -75,7 +77,7 @@ class MpExperienceSiriHTTP(MpExperience): s = MpExperienceSiriHTTP.JAVA_BIN + " -jar " + os.path.dirname(os.path.abspath(__file__)) + "/siriClient.jar " + \ self.mpConfig.getServerIP() + " 8080 " + self.run_time + " " + self.query_size + " " + self.response_size + \ " " + self.delay_query_response + " " + self.min_payload_size + " " + \ - self.max_payload_size + " " + self.interval_time_ms + " " + self.buffer_size + \ + self.max_payload_size + " " + self.interval_time_ms + " " + self.buffer_size + " " + self.burst_size + " " + self.interval_burst_time_ms + \ " >" + MpExperienceSiriHTTP.CLIENT_LOG + " 2>" + MpExperienceSiriHTTP.CLIENT_ERR print(s) return s diff --git a/src/mpExperienceSiriMsg.py b/src/mpExperienceSiriMsg.py index bfed0c2..19cf807 100644 --- a/src/mpExperienceSiriMsg.py +++ b/src/mpExperienceSiriMsg.py @@ -46,6 +46,8 @@ class MpExperienceSiriMsg(MpExperience): self.max_payload_size = self.xpParam.getParam(MpParamXp.SIRIMAXPAYLOADSIZE) self.interval_time_ms = self.xpParam.getParam(MpParamXp.SIRIINTERVALTIMEMS) self.buffer_size = self.xpParam.getParam(MpParamXp.SIRIBUFFERSIZE) + self.burst_size = self.xpParam.getParam(MpParamXp.SIRIBURSTSIZE) + self.interval_burst_time_ms = self.xpParam.getParam(MpParamXp.SIRIINTERVALBURSTTIMEMS) self.client_sleep = self.xpParam.getParam(MpParamXp.MSGCLIENTSLEEP) self.server_sleep = self.xpParam.getParam(MpParamXp.MSGSERVERSLEEP) self.nb_requests = self.xpParam.getParam(MpParamXp.MSGNBREQUESTS) @@ -75,7 +77,7 @@ class MpExperienceSiriMsg(MpExperience): s = MpExperienceSiriMsg.JAVA_BIN + " -jar " + os.path.dirname(os.path.abspath(__file__)) + "/siriClient.jar " + \ self.mpConfig.getServerIP() + " 8080 " + self.run_time + " " + self.query_size + " " + self.response_size + \ " " + self.delay_query_response + " " + self.min_payload_size + " " + \ - self.max_payload_size + " " + self.interval_time_ms + " " + self.buffer_size + \ + self.max_payload_size + " " + self.interval_time_ms + " " + self.buffer_size + " " + self.burst_size + " " + self.interval_burst_time_ms + \ " >" + MpExperienceSiriMsg.CLIENT_LOG + " 2>" + MpExperienceSiriMsg.CLIENT_ERR print(s) return s diff --git a/src/mpParamXp.py b/src/mpParamXp.py index 6793595..36ff5b7 100644 --- a/src/mpParamXp.py +++ b/src/mpParamXp.py @@ -48,6 +48,8 @@ class MpParamXp(MpParam): SIRIMAXPAYLOADSIZE = "siriMaxPayloadSize" SIRIINTERVALTIMEMS = "siriIntervalTimeMs" SIRIBUFFERSIZE = "siriBufferSize" + SIRIBURSTSIZE = "siriBurstSize" + SIRIINTERVALBURSTTIMEMS = "siriIntervalBurstTimeMs" VLCFILE = "vlcFile" VLCTIME = "vlcTime" DITGKBYTES = "ditgKBytes" @@ -138,6 +140,8 @@ class MpParamXp(MpParam): defaultValue[SIRIMAXPAYLOADSIZE] = "500" defaultValue[SIRIINTERVALTIMEMS] = "333" defaultValue[SIRIBUFFERSIZE] = "9" + defaultValue[SIRIBURSTSIZE] = "0" + defaultValue[SIRIINTERVALBURSTTIMEMS] = "0" defaultValue[VLCFILE] = "bunny_ibmff_360.mpd" defaultValue[VLCTIME] = "0" defaultValue[DITGKBYTES] = "10000" diff --git a/src/siriClient.jar b/src/siriClient.jar index 6c8009b5a9eb11159b17e57a1cf53d1702ad9fbd..b3b3326486ee5287a505f8f530f24a5862a1cd38 100644 GIT binary patch delta 6915 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 Y^54rQ_^(wVAw`0hM42)4h5s}7KY;c;4gdfE delta 6623 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