I’m trying to write an echoing client/server using UDP sockets in Python. I have programmed the server so that 30% of the packets are lost. My client has a timeout set to one second to account for packet loss. However, when I run the client, I keep getting the output “100% REQUEST TIMED OUT.”
I’m assuming that the problem lies in the fact that the server isn’t receiving the message, but I can’t figure out why this is happening. Here’s my code:
#### Server Code (Python UDP socket):
```python
import random
from socket import *
# Create a UDP socket
serverSocket = socket(AF_INET, SOCK_DGRAM)
# Assign IP address and port number to socket
serverSocket.bind(('', 12000))
while True:
# Generate random number in the range of 0 to 10
rand = random.randint(0, 10)
# Receive the client packet along with the address it is coming from
message, address = serverSocket.recvfrom(1024)
# Capitalize the message from the client
message = message.upper()
# If rand is less than 4, we consider the packet lost and do not respond
if rand < 4:
continue
# Otherwise, the server responds
serverSocket.sendto(message, address)
Client Code (Python UDP socket):
import time
from socket import *
pings = 1
# Send ping 10 times
while pings < 11:
# Create a UDP socket
clientSocket = socket(AF_INET, SOCK_DGRAM)
# Set a timeout value of 1 second
clientSocket.settimeout(1)
# Ping to server
message = 'test'
addr = ("127.0.0.1", 12000)
# Send ping
start = time.time()
clientSocket.sendto(message, addr)
# If data is received back from server, print
try:
data, server = clientSocket.recvfrom(1024)
end = time.time()
elapsed = end - start
print(data + " " + str(pings) + " " + str(elapsed))
# If data is not received back from server, print it has timed out
except timeout:
print('REQUEST TIMED OUT')
pings = pings + 1
One possible reason your client might be receiving timeouts is that the server might not be responding correctly. In the server code, the packet loss logic could be a contributing factor, and the server could fail to send responses back even if the message is received.
Solution: Ensure the server is correctly listening on the expected address and port, and the message is being received. Try printing debug messages in the server to confirm the message is being received, even if it’s discarded.
# Server code example:
import random
from socket import *
serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.bind(('', 12000))
while True:
rand = random.randint(0, 10)
message, address = serverSocket.recvfrom(1024)
print(f"Received message: {message} from {address}")
message = message.upper()
if rand < 4:
continue # Simulating packet loss
serverSocket.sendto(message, address) # Send response
print(f"Responding with: {message}")
In the client, ensure you’re using the correct address and port. Also, print out any received responses to check if the server is responding but your client is failing to process them.
The decrement logic for pings in the client is incorrect. You are decrementing pings instead of incrementing it, which might cause the client to exit the loop prematurely or not send as many pings.
Solution: Change the logic to properly increment pings after each ping.
# Client code example:
import time
from socket import *
pings = 1
while pings < 11:
clientSocket = socket(AF_INET, SOCK_DGRAM)
clientSocket.settimeout(1)
message = 'test'
addr = ("127.0.0.1", 12000)
start = time.time()
clientSocket.sendto(message, addr)
try:
data, server = clientSocket.recvfrom(1024)
end = time.time()
elapsed = end - start
print(data.decode() + " " + str(pings) + " " + str(elapsed))
except timeout:
print('REQUEST TIMED OUT')
pings += 1 # Increment instead of decrement
The way packet loss is simulated in the server is random. With 30% of packets being lost, it’s possible the client is timing out more often than expected, especially if the random number generator causes too many lost packets.
Solution: To ensure the server is not losing too many packets, you can temporarily reduce the packet loss rate or introduce a fixed loss condition for debugging purposes. For example, simulate loss only for specific packets.
# Server code example with reduced packet loss:
import random
from socket import *
serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.bind(('', 12000))
while True:
message, address = serverSocket.recvfrom(1024)
message = message.upper()
# Simulate packet loss (reduce loss for testing)
if random.random() < 0.2: # 20% chance of losing a packet
continue # Simulate packet loss
serverSocket.sendto(message, address) # Respond back
print(f"Sent message: {message}")
By adjusting the loss rate or controlling which packets are lost, you can observe if the client is getting responses and debug the timing or address issues.