日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【Java】模拟分组交换网络的时延、丢包

發(fā)布時間:2025/3/15 java 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java】模拟分组交换网络的时延、丢包 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ttrans & tprop

ttrans

這是傳輸時延,是將所有分組的比特推向鏈路(即傳輸,或者說發(fā)射)所需要的時間。

tprop

這是傳播時延,是從鏈路的起點到路由器B傳播所需要的時間。

區(qū)別

打個比方:
【背景】高速公路收費站口A到B上有一個速度一樣的、含有很多車的車隊……
【模擬】一個車相當于一個比特,一個車隊相當于一個分組,收費站相當于路由器,高速路相當于傳輸比特的物理媒體……
【情景分析】
過了A收費站后,從A到B,這段走在高速路上的時間,相當于傳播時延。
而汽車們到了收費站B處需要排隊等待(假設只有一個收費窗口),排隊和放行需要時間,排隊等待放行的時間是傳輸時延。

設計思路

我們既然要讓網絡擁塞導致緩存區(qū)滿丟包,那就要讓ttrans > tprop。不妨設傳輸時延為2s,傳播時間為1s,使得現象更明顯些。

數據結構

模擬緩存區(qū)要使用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

異常

要注意的是我們?yōu)樯厦娴漠惓G闆r設置了兩個異常類:

出隊隊空異常

private static class QueueEmptyException extends Exception { }

入隊隊滿異常

private static class QueueFullException extends Exception { }

線程

需要兩種線程,一種是入隊線程,另一種是出隊線程。

為了能sleep(),進而控制節(jié)奏,就允許它們繼承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("發(fā)生丟包");}} }

出現異常就提示丟包。

出隊線程

private static class deQueueThread extends Thread {@Overridepublic void run() {try {System.out.println("第" + queue.deQueue() + "個包被發(fā)送");} catch (QueueEmptyException e) {System.out.println("沒有可發(fā)送的包");}} }

出現異常就提示沒有可發(fā)的包。

完整代碼

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("發(fā)生丟包");}}}private static class deQueueThread extends Thread {@Overridepublic void run() {try {System.out.println("第" + queue.deQueue() + "個包被發(fā)送");} catch (QueueEmptyException e) {System.out.println("沒有可發(fā)送的包");}}}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個包被發(fā)送 第2個包被發(fā)送 第3個包被發(fā)送 第4個包被發(fā)送 第5個包被發(fā)送 發(fā)生丟包 第6個包被發(fā)送 發(fā)生丟包 第7個包被發(fā)送 發(fā)生丟包 第8個包被發(fā)送 發(fā)生丟包 第9個包被發(fā)送 發(fā)生丟包 第10個包被發(fā)送 發(fā)生丟包 第12個包被發(fā)送 發(fā)生丟包 第14個包被發(fā)送 發(fā)生丟包 第16個包被發(fā)送 發(fā)生丟包 第18個包被發(fā)送 發(fā)生丟包 第20個包被發(fā)送 發(fā)生丟包 第22個包被發(fā)送 發(fā)生丟包 第24個包被發(fā)送 發(fā)生丟包 第26個包被發(fā)送 發(fā)生丟包 第28個包被發(fā)送 發(fā)生丟包 第30個包被發(fā)送 發(fā)生丟包 第32個包被發(fā)送 發(fā)生丟包 第34個包被發(fā)送 ……

測試網絡空閑的情況

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個包被發(fā)送 沒有可發(fā)送的包 第2個包被發(fā)送 沒有可發(fā)送的包 第3個包被發(fā)送 沒有可發(fā)送的包 第4個包被發(fā)送 沒有可發(fā)送的包 第5個包被發(fā)送 沒有可發(fā)送的包 第6個包被發(fā)送 沒有可發(fā)送的包 第7個包被發(fā)送 沒有可發(fā)送的包

總結

ttrans 和 tprop 之間還是有不小差別的,這里我們用一種模擬的方式來直觀地驗證這二者的差別,希望能使讀者更清楚這二者的差別。

代碼使用Java編寫,原創(chuàng)不易,感謝支持orz

總結

以上是生活随笔為你收集整理的【Java】模拟分组交换网络的时延、丢包的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。