-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
161 lines (149 loc) · 3.54 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package main
import (
"fmt"
"github.com/fatih/color"
"log"
"math/rand"
"time"
)
var (
messages = "Hello World! Hello KNTU, the best place that exists in the world :|"
frameNumber = 0
t time.Time
propagation int
bandwidth int
fs int
flag = false
tf float64
prompt = color.New(color.FgGreen)
serverColor = color.New(color.FgHiMagenta)
clientColor = color.New(color.FgHiYellow)
ackColor = color.New(color.FgHiGreen)
timeoutColor = color.New(color.FgHiRed)
)
func server(data chan []byte, ack chan bool, done chan bool) {
messageInByte := []byte(messages)
counter := 0
var a bool
buffer := make([]byte, fs)
for _, b := range messageInByte {
//Start Timer
total := time.Now()
// Make a frame to send
if counter != fs-1 {
flag = false
buffer[counter] = b
counter++
} else {
buffer[counter] = b
t = time.Now()
// Print Send Log
clientSendLog(buffer, t)
//Simulate Propagation and Transmission Time
clientSendTimeSimulation()
//Send Frame
data <- buffer
// Listen for Ack
t = time.Now()
a = <-ack
// Implement Timeout mechanism
failed := 0
if !a {
timeoutMechanism(data, ack, buffer, &failed)
}
// Break connection if after 3 time No ack was received
if failed == 3 {
break
}
_, _ = ackColor.Printf("Ack Time: %s, Total Time: %s\n", time.Now().Sub(t), time.Now().Sub(total))
frameNumber++
counter = 0
flag = true
}
}
if !flag {
total := time.Now()
for counter < len(buffer) {
buffer[counter] = 0
counter++
}
t = time.Now()
clientSendLog(buffer, t)
clientSendTimeSimulation()
data <- buffer
t = time.Now()
a = <-ack
frameNumber++
failed := 0
if !a {
timeoutMechanism(data, ack, buffer, &failed)
}
if failed != 3 {
_, _ = ackColor.Printf("Ack Time: %s, Total Time: %s\n", time.Now().Sub(t), time.Now().Sub(total))
}
}
close(data)
close(ack)
done <- true
}
func client(data chan []byte, ack chan bool) {
for data != nil {
for b := range data {
p := rand.Float64()
if p <= 0.8 {
_, _ = serverColor.Println("Receiver: ")
fmt.Println("\tFrame", frameNumber, " Received:", string(b[0:]), time.Now())
time.Sleep(time.Duration(propagation) * time.Microsecond)
ack <- true
} else {
ack <- false
}
}
}
}
func main() {
_, _ = prompt.Println("Enter Propagation Time and Bandwidth: ")
_, err := fmt.Scanf("%d %d", &propagation, &bandwidth)
if err != nil {
log.Fatalln("Fatal Error")
}
_, _ = prompt.Println("Enter Frame Size")
_, err = fmt.Scanf("%d", &fs)
if err != nil {
log.Fatalln("Fatal Error")
}
tf = float64(fs / bandwidth)
data := make(chan []byte, fs)
ack := make(chan bool, 1)
done := make(chan bool)
go server(data, ack, done)
go client(data, ack)
<-done
}
func clientSendLog(buffer []byte, t time.Time) {
_, _ = clientColor.Println("Transmitter: ")
_, _ = clientColor.Printf("\tFrame %d Sent:%s %s \n", frameNumber, buffer, t)
}
func clientSendTimeSimulation() {
time.Sleep(time.Duration(propagation) * time.Microsecond)
time.Sleep(time.Duration(tf) * time.Second)
}
func timeoutMechanism(data chan []byte, ack chan bool, buffer []byte, failed *int) {
fmt.Println("Timeout")
var a bool
for i := 0; i < 3; i++ {
time.Sleep(1 * time.Millisecond)
t = time.Now()
_, _ = clientColor.Println("Transmitter: ")
fmt.Printf("\tFrame %d Sent:%s %s \n", frameNumber, buffer, time.Now())
clientSendTimeSimulation()
data <- buffer
a = <-ack
if !a {
_, _ = timeoutColor.Println("Timeout")
*failed++
} else {
break
}
}
}