-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.py
149 lines (131 loc) · 5.87 KB
/
server.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
147
148
149
import socket
import random
import time
# unreliableSend fonksiyonu
# Hata oranını (errRate) simüle eden yardımcı fonksiyon
def unreliableSend(packet, sock, userIP, errRate):
if errRate < random.randint(0, 100):
sock.sendto(packet, userIP)
if(packet[0]==3): print("Fin gönderildi")
elif packet[0]==1: print(f" ACK: Paket gönderildi-> {packet[1]}")
elif packet[0]==0: print(f" Handshake: Paket gönderildi")
else:
print(f" Paket gönderildi -> {packet[2]}")
else:
if(packet[0]==3): print("Fin kayboldu")
elif packet[0]==1: print(f" ACK: Paket kayboldu-> {packet[1]}")
elif packet[0]==0: print(f" Handshake: Paket kayboldu")
else : print(f"Paket kayboldu -> {packet[2]}")
def main():
server_cocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_cocket.bind(('localhost', 10000)) # Sunucu adresi ve portu
errRate = 20 # Hata oranı (%)
timeout = 0.0001 # Timeout süresi (saniye)
# Triple Handshake
print("Witing handshake...")
filename = "data.txt"
# Triple Handshake
while True:
packet, client_address = server_cocket.recvfrom(1024)
packet_type = packet[0]
if packet_type == 0: # Handshake paketi
filename_length = packet[1]
file_name = packet[2:2 + filename_length].decode('utf-8')
if file_name == filename:
print(f"Requested file: {filename}.")
# ACK gönder
ack_packet = bytearray([1]) + (0).to_bytes(1, 'big')
unreliableSend(ack_packet, server_cocket, client_address, errRate)
# ACK bekle
server_cocket.settimeout(0.0001)
try:
ack_response, _ = server_cocket.recvfrom(1024)
if ack_response[0] == 1 and ack_response[1] == 0:
print("ACK for handshake received from client. Handshake completed. Data transfer started.")
break
except socket.timeout:
print("Timeout waiting for client's ACK. Closing connection.")
server_cocket.close()
return
else: # Hatalı dosya adı
print(f"Requested file: {file_name}. Wrong file name. Closing connection.")
server_cocket.close()
return
# Dosya Gönderimi
with open(filename, 'r') as f:
data = f.readlines()
base = 0 # Gönderilen en düşük sıra numarası
next_seq_num = 0 # Gönderilecek sıradaki paket numarası
window_size = 4 # Pencere boyutu
timers = {} # Her paket için zamanlayıcı
sent_packets = {} # Gönderilen paketler
acked_packets = set() # Alınan ACK'leri tutmak için set
while base < len(data):
# Pencereyi doldur
while next_seq_num < base + window_size and next_seq_num < len(data):
packet_data = data[next_seq_num].strip()
data_packet = bytearray([2]) + len(packet_data).to_bytes(1, 'big') + next_seq_num.to_bytes(1, 'big') + packet_data.encode('utf-8')
unreliableSend(data_packet, server_cocket, client_address, errRate)
sent_packets[next_seq_num] = data_packet
timers[next_seq_num] = time.time()
print(f"Packet {next_seq_num} sent: {packet_data}")
next_seq_num += 1
# ACK alımı
try:
packet, _ = server_cocket.recvfrom(1024)
ack_type = packet[0]
ack_num = packet[1]
if ack_type == 1: # ACK paketi
print(f"ACK received for packet {ack_num}")
acked_packets.add(ack_num)
if ack_num in sent_packets:
del sent_packets[ack_num]
del timers[ack_num]
while base in acked_packets:
print(f"Base updated: {base}")
acked_packets.remove(base)
base += 1
except socket.timeout:
# Timeout kontrolü ve yeniden gönderim
current_time = time.time()
for seq_num, sent_time in list(timers.items()):
if current_time - sent_time > timeout:
print(f"Timeout: Packet {seq_num} not acknowledged, resending...")
unreliableSend(sent_packets[seq_num], server_cocket, client_address, errRate)
timers[seq_num] = time.time()
print("Paket gönderimi tamamlandı.")
# FIN gönderimi
fin_packet = bytearray([3])+ (seq_num+1).to_bytes(1, 'big')
unreliableSend(fin_packet, server_cocket, client_address, errRate)
print("FIN packet sent. Waiting for FIN-ACK...")
# FIN-ACK bekleme
while True:
try:
packet, _ = server_cocket.recvfrom(1024)
packet_type = packet[0]
if packet_type == 1 and packet[1] == len(data)+1: # FIN-ACK
print("FIN-ACK received from server.")
break
except socket.timeout:
print("Timeout! Closing server..")
server_cocket.close()
return
# Sunucudan FIN bekleme
while True:
try:
packet, _ = server_cocket.recvfrom(1024)
packet_type = packet[0]
if packet_type == 3: # Server FIN
print("FIN received from server. Sending final ACK...")
ack_packet = bytearray([1]) + (len(data)+1).to_bytes(1, 'big')
unreliableSend(ack_packet, server_cocket, client_address, errRate)
print("Final ACK sent. Closing connection.")
break
except socket.timeout:
print("Timeout! Closing server..")
server_cocket.close()
return
server_cocket.close()
return
if __name__ == "__main__":
main()