-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient_scenario5.py
More file actions
91 lines (73 loc) · 3.33 KB
/
client_scenario5.py
File metadata and controls
91 lines (73 loc) · 3.33 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
# client_scenario5.py
# This client tests the server's ability to handle duplicate data packets.
# It sends the same packet twice to simulate a retransmission after a lost ACK.
import socket
import random
import time
from packet import TCPPacket
# --- Settings ---
SERVER_HOST = '127.0.0.1'
SERVER_PORT = 12345
TIMEOUT_SECONDS = 5
MSS = 100
def main():
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# --- Phase 1: Handshake (Unchanged) ---
print("\n[Client - Handshake]")
client_seq = random.randint(10001, 20000)
# ... (Handshake code)
syn_packet = TCPPacket(src_port=0, dest_port=SERVER_PORT, seq_num=client_seq, ack_num=0, syn=1)
client_socket.sendto(syn_packet.to_bytes(), (SERVER_HOST, SERVER_PORT))
client_port = client_socket.getsockname()[1]
client_socket.settimeout(TIMEOUT_SECONDS)
syn_ack_data, _ = client_socket.recvfrom(4096)
syn_ack_packet = TCPPacket.from_bytes(syn_ack_data)
client_ack = syn_ack_packet.seq_num + 1
client_seq += 1
ack_packet = TCPPacket(src_port=client_port, dest_port=SERVER_PORT, seq_num=client_seq, ack_num=client_ack, ack=1)
client_socket.sendto(ack_packet.to_bytes(), (SERVER_HOST, SERVER_PORT))
print("Connection Established.")
# --- Phase 2: Data Transfer - Duplicate Packet Scenario ---
print("\n[Phase 2: Data Transfer - Duplicate Packet Scenario]")
message = "This is a test for duplicate packet handling."
data_to_send = message.encode('utf-8')
# Create the data packet
data_packet = TCPPacket(
src_port=client_port, dest_port=SERVER_PORT,
seq_num=client_seq, ack_num=client_ack, payload=data_to_send
)
# *** Scenario Logic: Send the same packet twice ***
# 1. Send the packet for the first time
print(f"\nSending packet for the first time: {data_packet}")
client_socket.sendto(data_packet.to_bytes(), (SERVER_HOST, SERVER_PORT))
# Wait for the first ACK from the server
try:
client_socket.settimeout(3)
ack1_bytes, _ = client_socket.recvfrom(4096)
ack1 = TCPPacket.from_bytes(ack1_bytes)
print(f"Client received the first ACK: {ack1}")
print("--> Simulating that this ACK was 'lost' on its way to the client.")
except socket.timeout:
print("Did not receive the first ACK from the server.")
print("\nWaiting 1 second before retransmitting...")
time.sleep(1)
# 2. Send the exact same packet again (the duplicate)
print(f"Retransmitting the same packet (the duplicate): {data_packet}")
client_socket.sendto(data_packet.to_bytes(), (SERVER_HOST, SERVER_PORT))
# Wait for the second ACK from the server
try:
client_socket.settimeout(3)
ack2_bytes, _ = client_socket.recvfrom(4096)
ack2 = TCPPacket.from_bytes(ack2_bytes)
print(f"Client received the second ACK: {ack2}")
if ack1.ack_num == ack2.ack_num:
print("\nSuccess! Server correctly re-sent the same ACK for the duplicate packet.")
else:
print("\nFailure! Server sent a different ACK for the duplicate packet.")
except socket.timeout:
print("Did not receive the second ACK from server.")
# --- Phase 3: Termination (Simplified) ---
print("\nScenario finished. Shutting down.")
client_socket.close()
if __name__ == "__main__":
main()