Using UDP sockets, you will write a client and server program that enables the c
ID: 3752583 • Letter: U
Question
Using UDP sockets, you will write a client and server program that enables the client to determine the round-trip time (RTT) to the server. To determine the RTT delay, the client records the time on sending a ping request to the server, and then records the time on receiving a ping response from the server. The difference in the two times is the RTT. The ping message contains 2 4-byte integers and must be encoded in network-byte order as follows : • 4-byte message type with an integer value of 1 or 2 o Message type = 1 for a ping request (message from client to server) o Message type =2 for a ping response (message from server to client) • 4-byte sequence number with a unique integer value starting from 1 . In the ping response, the server should echo back the client’s sequence number. The client program should take the following input parameters: • IP address of server • IP port of server The client program will read in the above input parameters, and send 10 ping requests consecutively, waiting for a response each time, to the server running at the specified IP address and port. After each response is received, the client calculates and prints the RTT for the message. If no response is received within a certain amount of time (one second) , the client notes that the request timed out and then sends the next request up to the maximum. The program output should print out trace information when data is sent and received, and account for error conditions. Trace output must include: • At start of output, print a message indicating the IP address and port of the server being pinged • For each ping response received, print RTT along with sequence number of ping message • For no ping response, print “Message timed out” along with sequence number of the ping message • After completion, print the following statistics (similar to output of UNIX ping utility); o Number of packets sent, received, lost (% loss rate) o Min, Max, Average RTT for all acknowledged ping packets The server will wait in an infinite loop to receive ping requests from the client. On receiving a ping request, the server program will randomly decide whether to respond to ping requests to simulate network packet loss. In the case that the server responds, it sends a ping response containing the appropriate message type, and client sequence number. In the case that the server decides not to respond, no ping response is sent, and the server waits for another ping request. To implement random “loss”, the server should generate a random integer between 0 and 10 and if the result is < 4, do not respond to the packet. In a ping request, the application data has the following format: 0 1 2 3 4 (bytes) +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Message Type (1= request) | -------------------------------------------------------------------------------- | Message sequence number (e.g. 5) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ In a ping response, the application data has the following format: 0 1 2 3 4 (bytes) +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Message Type (2 = response) | -------------------------------------------------------------------------------- | Message sequence number (e.g. 5) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Examples of the client program trace output are as follows: Pinging 127.0.0.1, 12000: Ping message number 1 timed out Ping message number 2 RTT: 0.002154 secs …. Ping message number 10 RTT: 0.000194 secs Examples of the server program trace output are as follows: The server is ready to receive on port: 12000 Message with sequence number 1 dropped Responding to ping request with sequence number 2 … Responding to ping request with sequence number 10 Notes: 1. Timestamp Resolution: When testing your program, especially when running client and server on the same host, you might find little difference in the timestamp values. The values will depend on the test environment, and timer resolution on your machine. If there are issues, you should simulate longer delays, by adding in a random "wait" or "sleep" function on the server before sending a ping response on receipt of a message. 2. Data structure Alignment and Padding Compilers on modern processors will typically try to align data structures to that optimal for the machine. For example, 4-byte values are stored at addresses divisible by 4, and 8-byte values are stored at addresses divisible by 8. When sending multiple values of different sizes, you may find that in data structures, such as “struct” in C/C++, the compiler adds padding. For example, if you are sending values of different sizes using a C struct to store a 4-byte integer, followed by an 8-byte integer, 4-bytes of padding may be inserted between the 2 integers to ensure 64-bit alignment. Thus, a struct of 12 bytes may become a struct of 16 bytes with this padding. (You can determine the size of the structure and the relevant fields in the structure using the sizeof() operator, and also looking at the wireshark output).
Explanation / Answer
# -------------------------Client Side Code ------------------------------------------- #
import socket
import time
# This function will create client
# @params
# server_ip : ip_address of server
# server_port : port at which server is running
def client(server_ip, server_port):
host = server_ip
port = server_port
# List to store the successful response recieved from server
RTT_list = []
# Total number of packets to send
total_packets = 10
# This will give the socket object
s = socket.socket()
# Timeout for client in seconds
s.settimeout(5)
# connect with the server
s.connect((host, port))
print('Pining ' + str(server_ip) + ',' + str(server_port) + ':')
# Create a for loop to send packets
for send_data in range(1, total_packets + 1):
# Start the timer when the packet is send
startTime = time.time()
try:
# Send the 1st part of packet
s.send(bytes('1', encoding='UTF8'))
# Send message in packet to server
s.send(bytes(str(send_data) + '', encoding='UTF8'))
# Recieve response from server
# Client will wait for "timeout" seconds, and then throw an timeout exception,
# which I have catched in except, and shows timeout.
# Currently it is 5 seconds
resType = s.recv(1024)
res = s.recv(1024)
# Calculate end time if response came from server
endTime = time.time()
# Caluclate RTT
RTT = endTime - startTime
# Add RTT to list
RTT_list.append(RTT)
print('Ping message number ' + str(send_data) +
' RTT:' + str(RTT) + ' secs...')
except Exception as e:
# If response will not come in 5 seconds. it will throw an exception
print('Ping message number ' + str(send_data) + ' timed out.')
print('Total pacekts send:', total_packets)
print('Recieved', len(RTT_list))
print('Lost', total_packets - len(RTT_list))
print('Min RTT', min(RTT_list), 'secs')
print('Max RTT', max(RTT_list), 'secs')
print('Average RTT', sum(RTT_list) / len(RTT_list), 'secs')
s.close()
print('Connection closed')
if __name__ == '__main__':
client(socket.gethostname(), 63000)
# ----------------------------------------------------------------------------------------------#
# -------------------------Server Side Code ------------------------------------------- #
import socket # Import socket module
import random
# Reserve a port for your service (*client must connect with this port number)
port = 63000
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection and listen for requests
total_packets = 10 # Total packets each new client will send
# This function will create server, running at port 63000
def serve():
print('Server is ready to recieve on port', port)
while True:
conn, addr = s.accept() # Establish connection with client, returns a tuple
for i in range(total_packets):
# Recieve type and data from client
recvType = conn.recv(1024)
data = conn.recv(1024)
# Calculate random number between 0,10
isResponse = random.sample(range(10), 10)[4]
# if isRespomse is > 4, sever will responsd will type 2 and same data as recived from client
if(isResponse > 4):
print('Responding to ping reuqest with sequence number', str(data))
conn.send(bytes('2', encoding='UTF8'))
conn.send(bytes(str(data) + '', encoding='UTF8'))
else:
# If isResponse < 4, server will not response simulating, timed out and packet dropped
print('Message with sequence number', str(data), 'dropped')
conn.close()
if __name__ == '__main__':
serve()
# ----------------------------------------------------------------------------------------------#
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.