forked from SongClass/SimTCP
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproject_timer.py
More file actions
executable file
·118 lines (95 loc) · 3.04 KB
/
project_timer.py
File metadata and controls
executable file
·118 lines (95 loc) · 3.04 KB
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
"""
Where solution code to project should be written. No other files should
be modified.
"""
import socket
import io
import time
import typing
import struct
import util
import util.logging
import threading
from threading import Timer
packet = []
sock_g = []
class RepeatTimer(Timer):
def run(self):
while not self.finished.wait(self.interval):
self.function(*self.args, **self.kwargs)
def resend():
# global sock_g
sock_g.send(packet)
print("$$$ resend:", packet)
def send(sock: socket.socket, data: bytes):
"""
Implementation of the sending logic for sending data over a slow,
lossy, constrained network.
Args:
sock -- A socket object, constructed and initialized to communicate
over a simulated lossy network.
data -- A bytes object, containing the data to send over the network.
"""
# Naive implementation where we chunk the data to be sent into
# packets as large as the network will allow, and then send them
# over the network, pausing half a second between sends to let the
# network "rest" :)
logger = util.logging.get_logger("project-sender")
chunk_size = util.MAX_PACKET
pause = .1
offsets = range(0, len(data), util.MAX_PACKET)
global packet
global sock_g
sock_g = sock
timer = RepeatTimer(0.2, resend) # repeat every 200 ms
for chunk in [data[i:i + chunk_size] for i in offsets]:
packet = chunk
sock.send(packet)
logger.info("Pausing for %f seconds", round(pause, 2))
time.sleep(pause)
if not timer.is_alive():
logger.info("start timer resending ...")
timer.start()
# time.sleep(5)
if timer.is_alive():
timer.cancel()
def recv(sock: socket.socket, dest: io.BufferedIOBase) -> int:
"""
Implementation of the receiving logic for receiving data over a slow,
lossy, constrained network.
Args:
sock -- A socket object, constructed and initialized to communicate
over a simulated lossy network.
Return:
The number of bytes written to the destination.
"""
logger = util.logging.get_logger("project-receiver")
# Naive solution, where we continually read data off the socket
# until we don't receive any more data, and then return.
num_bytes = 0
while True:
data = sock.recv(util.MAX_PACKET)
if not data:
break
logger.info("Received %d bytes", len(data))
dest.write(data)
num_bytes += len(data)
dest.flush()
return num_bytes
# Below is a program to show timer test alone through 'python3 project_timer.py'
# It is not needed for the project.
from threading import Timer
import time
class RepeatTimer(Timer):
def run(self):
while not self.finished.wait(self.interval):
self.function(*self.args, **self.kwargs)
def dummyfn(msg="foo"):
print(msg)
def main():
timer = RepeatTimer(1, dummyfn)
timer.start()
time.sleep(5)
timer.cancel()
if __name__ == '__main__':
main()