【Java】模拟分组交换网络的时延、丢包
ttrans & tprop
ttrans
這是傳輸時延,是將所有分組的比特推向鏈路(即傳輸,或者說發射)所需要的時間。
tprop
這是傳播時延,是從鏈路的起點到路由器B傳播所需要的時間。
區別
打個比方:
【背景】高速公路收費站口A到B上有一個速度一樣的、含有很多車的車隊……
【模擬】一個車相當于一個比特,一個車隊相當于一個分組,收費站相當于路由器,高速路相當于傳輸比特的物理媒體……
【情景分析】
過了A收費站后,從A到B,這段走在高速路上的時間,相當于傳播時延。
而汽車們到了收費站B處需要排隊等待(假設只有一個收費窗口),排隊和放行需要時間,排隊等待放行的時間是傳輸時延。
設計思路
我們既然要讓網絡擁塞導致緩存區滿丟包,那就要讓ttrans > tprop。不妨設傳輸時延為2s,傳播時間為1s,使得現象更明顯些。
數據結構
模擬緩存區要使用FIFO隊列,為使用方便我選擇了自己手寫一個鏈式隊列。
定義結點
為簡便起見,使用單鏈表式的鏈隊列比較好,所以需要一個單鏈表結點:
private static class Node<T> {T value;Node<T> next;Node(T value) {this.value = value;} }定義隊列
隊列設置一下size,因為需要與MAX_SIZE做比較。
要有指向隊首和隊尾的兩個指針,head和rear。
需要isFull()、isEmpty()這兩個判隊列滿和隊列空的函數。
enQueue()是入隊操作,要判滿;deQueue()是出隊操作,要判空。
其余不講,數據結構的內容而已……
private static class Queue<T> {private static final int MAX_SIZE = 5;int size;Node<T> head, rear;synchronized void enQueue(T value) throws QueueFullException {if (isFull()) {throw new QueueFullException();}Node<T> newNode = new Node<>(value);if (isEmpty()) {rear = head = newNode;} else {rear.next = newNode;rear = newNode;}++size;}synchronized T deQueue() throws QueueEmptyException {if (isEmpty()) {throw new QueueEmptyException();}Node<T> removeNode = head;head = head.next;--size;return removeNode.value;}private boolean isEmpty() {return size == 0;}private boolean isFull() {return size == MAX_SIZE;} }為了同步就加上synchronized吧 orz
異常
要注意的是我們為上面的異常情況設置了兩個異常類:
出隊隊空異常
private static class QueueEmptyException extends Exception { }入隊隊滿異常
private static class QueueFullException extends Exception { }線程
需要兩種線程,一種是入隊線程,另一種是出隊線程。
為了能sleep(),進而控制節奏,就允許它們繼承Thread吧,Runnable反而顯得不便。
入隊線程
private static class enQueueThread extends Thread {int counter;enQueueThread(int counter) {this.counter = counter;}@Overridepublic void run() {try {queue.enQueue(counter);} catch (QueueFullException e) {System.out.println("發生丟包");}} }出現異常就提示丟包。
出隊線程
private static class deQueueThread extends Thread {@Overridepublic void run() {try {System.out.println("第" + queue.deQueue() + "個包被發送");} catch (QueueEmptyException e) {System.out.println("沒有可發送的包");}} }出現異常就提示沒有可發的包。
完整代碼
package org.self.test.net;public class PackageLostTest {private static Queue<Integer> queue = new Queue<>();private static class QueueEmptyException extends Exception { }private static class QueueFullException extends Exception { }private static class Node<T> {T value;Node<T> next;Node(T value) {this.value = value;}}private static class Queue<T> {private static final int MAX_SIZE = 5;int size;Node<T> head, rear;synchronized void enQueue(T value) throws QueueFullException {if (isFull()) {throw new QueueFullException();}Node<T> newNode = new Node<>(value);if (isEmpty()) {rear = head = newNode;} else {rear.next = newNode;rear = newNode;}++size;}synchronized T deQueue() throws QueueEmptyException {if (isEmpty()) {throw new QueueEmptyException();}Node<T> removeNode = head;head = head.next;--size;return removeNode.value;}private boolean isEmpty() {return size == 0;}private boolean isFull() {return size == MAX_SIZE;}}private static class enQueueThread extends Thread {int counter;enQueueThread(int counter) {this.counter = counter;}@Overridepublic void run() {try {queue.enQueue(counter);} catch (QueueFullException e) {System.out.println("發生丟包");}}}private static class deQueueThread extends Thread {@Overridepublic void run() {try {System.out.println("第" + queue.deQueue() + "個包被發送");} catch (QueueEmptyException e) {System.out.println("沒有可發送的包");}}}public static void main(String[] args) throws InterruptedException {int counter = 0;while (true) {enQueueThread thread1 = new enQueueThread(++counter);deQueueThread thread2 = new deQueueThread();thread1.start();thread2.start();Thread.sleep(1000);enQueueThread thread3 = new enQueueThread(++counter);thread3.start();Thread.sleep(1000);}}}測試丟包的結果
只截取運行到34個包的結果:
第1個包被發送 第2個包被發送 第3個包被發送 第4個包被發送 第5個包被發送 發生丟包 第6個包被發送 發生丟包 第7個包被發送 發生丟包 第8個包被發送 發生丟包 第9個包被發送 發生丟包 第10個包被發送 發生丟包 第12個包被發送 發生丟包 第14個包被發送 發生丟包 第16個包被發送 發生丟包 第18個包被發送 發生丟包 第20個包被發送 發生丟包 第22個包被發送 發生丟包 第24個包被發送 發生丟包 第26個包被發送 發生丟包 第28個包被發送 發生丟包 第30個包被發送 發生丟包 第32個包被發送 發生丟包 第34個包被發送 ……測試網絡空閑的情況
public static void main(String[] args) throws InterruptedException {int counter = 0;while (true) {enQueueThread thread1 = new enQueueThread(++counter);deQueueThread thread2 = new deQueueThread();thread1.start();thread2.start();Thread.sleep(1000);deQueueThread thread3 = new deQueueThread();thread3.start();Thread.sleep(1000);} }只截取運行到7個包的結果:
第1個包被發送 沒有可發送的包 第2個包被發送 沒有可發送的包 第3個包被發送 沒有可發送的包 第4個包被發送 沒有可發送的包 第5個包被發送 沒有可發送的包 第6個包被發送 沒有可發送的包 第7個包被發送 沒有可發送的包總結
ttrans 和 tprop 之間還是有不小差別的,這里我們用一種模擬的方式來直觀地驗證這二者的差別,希望能使讀者更清楚這二者的差別。
代碼使用Java編寫,原創不易,感謝支持orz
總結
以上是生活随笔為你收集整理的【Java】模拟分组交换网络的时延、丢包的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 查看表和视图信息
- 下一篇: const int 和INT const