-
Notifications
You must be signed in to change notification settings - Fork 0
/
testserverone.py
149 lines (135 loc) · 5.01 KB
/
testserverone.py
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
import socket
from zlib import crc32
from ReliableUDP import *
from http10 import *
SRC_ADDR, SRC_PORT = "localhost", 9999
server = "apache 2.0"
# SOCK_DGRAM is the socket type to use for UDP sockets
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((SRC_ADDR, SRC_PORT))
client_connection = ClientConnectionInfo()
while True:
client_connection.receive_data_buffer = []
sock.settimeout(None)
print("Server start...")
packet, (DEST_ADDR, DEST_PORT) = sock.recvfrom(MAX_PACKET_SIZE)
header = unpack(PACK_FORMAT, packet[:HEADER_LENGTH])
checksum = header[0]
num = header[1]
ack = header[2]
fin = header[3]
more = header[4]
packet = (
pack(
PACK_FORMAT,
0,
header[1],
header[2],
header[3],
header[4],
)
+ packet[HEADER_LENGTH:]
)
if (
crc32(packet) == checksum
and num == client_connection.num
and not ack
and not fin
):
client_connection.receive_data_buffer.append(
packet[HEADER_LENGTH:].decode())
sock.settimeout(PACKET_LOSS_TIMEOUT)
more = 1
while more:
try:
response_packet = get_ack_packet(client_connection.num)
sock.sendto(response_packet, (DEST_ADDR, DEST_PORT))
packet, (DEST_ADDR, DEST_PORT) = sock.recvfrom(MAX_PACKET_SIZE)
header = unpack(PACK_FORMAT, packet[:HEADER_LENGTH])
checksum = header[0]
num = header[1]
ack = header[2]
fin = header[3]
more = header[4]
packet = (
pack(
PACK_FORMAT,
0,
header[1],
header[2],
header[3],
header[4],
)
+ packet[HEADER_LENGTH:]
)
if (
crc32(packet) != checksum
or num != client_connection.num
or fin
):
raise socket.timeout
elif ack:
client_connection.num = not client_connection.num
else:
client_connection.receive_data_buffer.append(
packet[HEADER_LENGTH:].decode()
)
client_connection.num = not client_connection.num
except socket.timeout:
sock.sendto(response_packet, (DEST_ADDR, DEST_PORT))
complete_request = "".join(client_connection.receive_data_buffer)
if complete_request[:3] == "GET":
file_name = complete_request.split(" ")[1].replace("/", "")
try:
f = open(file_name, "r")
status_code = 200
status = "OK"
file_content = f.read()
except FileNotFoundError:
print("File not found! Check the path variable and filename")
status_code = 404
status = "NOT FOUND"
file_content = ""
http_response = get_http_response(
"GET", status_code, status, file_content, server
)
elif complete_request[:4] == "POST":
http_response = get_http_response("POST", 200, "OK", "", server)
client_connection.send_packets_buffer = get_packets(
http_response, client_connection.num
)
while len(client_connection.send_packets_buffer):
next_packet = client_connection.send_packets_buffer.pop(0)
sock.sendto(next_packet, (DEST_ADDR, DEST_PORT))
while True:
try:
packet, (addr, port) = sock.recvfrom(MAX_PACKET_SIZE)
# check not corrupted
header = unpack(PACK_FORMAT, packet[:HEADER_LENGTH])
checksum = header[0]
num = header[1]
ack = header[2]
fin = header[3]
packet = (
pack(
PACK_FORMAT,
0,
header[1],
header[2],
header[3],
header[4],
)
+ packet[HEADER_LENGTH:]
)
if crc32(packet) == checksum:
if num != client_connection.num or not ack or fin:
raise socket.timeout
client_connection.num = not client_connection.num
break
else:
raise socket.timeout # resend last packet
except socket.timeout:
sock.sendto(next_packet, (DEST_ADDR, DEST_PORT))
print(complete_request)
else:
print("Invalid request!")