-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient_scenario4.py
More file actions
97 lines (79 loc) · 3.55 KB
/
client_scenario4.py
File metadata and controls
97 lines (79 loc) · 3.55 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
# client_scenario4.py
# This client tests the server's ability to handle out-of-order packets.
# It sends Segment 2 first, then Segment 1.
import socket
import random
import threading
import time
from packet import TCPPacket
# --- Settings ---
SERVER_HOST = '127.0.0.1'
SERVER_PORT = 12345
TIMEOUT_SECONDS = 5
MSS = 50 # Use a smaller MSS to easily create 2 segments
# We don't need retransmission for this specific scenario
RETRANSMISSION_TIMEOUT = 999
# --- Global variables & Helper Functions ---
# We don't need a receiver thread for this simple, controlled scenario.
program_active = True
def main():
global program_active
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 - Out-of-Order Scenario ---
print("\n[Phase 2: Data Transfer - Out-of-Order Scenario]")
message = "First-Part_Second-Part"
data_to_send = message.encode('utf-8')
# Split into two segments
segment1_data = data_to_send[:11] # "First-Part"
segment2_data = data_to_send[11:] # "_Second-Part"
# Create packets for both segments
packet1 = TCPPacket(
src_port=client_port, dest_port=SERVER_PORT,
seq_num=client_seq, ack_num=client_ack, payload=segment1_data
)
packet2 = TCPPacket(
src_port=client_port, dest_port=SERVER_PORT,
seq_num=client_seq + len(segment1_data), ack_num=client_ack, payload=segment2_data
)
# *** Scenario Logic: Send Packet 2 first, then Packet 1 ***
print(f"Sending Packet 2 (Out of Order): {packet2}")
client_socket.sendto(packet2.to_bytes(), (SERVER_HOST, SERVER_PORT))
print("Waiting 1 second to send Packet 1...")
time.sleep(1)
print(f"Sending Packet 1 (The 'Missing' Packet): {packet1}")
client_socket.sendto(packet1.to_bytes(), (SERVER_HOST, SERVER_PORT))
# Wait for the final cumulative ACK
try:
client_socket.settimeout(3)
# We expect two ACKs, but we only care about the final one
final_ack_bytes, _ = client_socket.recvfrom(4096)
final_ack_bytes, _ = client_socket.recvfrom(4096)
final_ack = TCPPacket.from_bytes(final_ack_bytes)
print(f"\nClient received final cumulative ACK: {final_ack}")
if final_ack.ack_num == client_seq + len(data_to_send):
print("Server correctly processed both segments. Success!")
else:
print("Server did not send the correct final ACK.")
except socket.timeout:
print("Did not receive final ACK from server.")
# --- Phase 3: Termination (Simplified for this scenario) ---
# We skip the full termination handshake for this simple test.
print("\nScenario finished. Shutting down.")
client_socket.close()
if __name__ == "__main__":
main()