Search code examples
pythonsockets

UDP Client/Server Socket in Python


I am trying to write an echoing client/server socket. I have written the server so that 30% of the packets are lost. I programmed my client to timeout after one second since the packet could be lost. However, whenever I run my client socket, my output is 100% REQUEST TIMED OUT. I'm assuming I'm getting this output because my server is never receiving the message. I've looked over my code multiple times and cannot figure out why I am constantly getting this output.

Server:

# We will need the following module to generate randomized lost packets
import random
from socket import *

# Create a UDP socket
# Notice the use of SOCK_DGRAM for UDP packets
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 is than 4, we consider the packet lost and do notrespond
    if rand < 4:
        continue
    
    # Otherwise, the server responds
    serverSocket.sendto(message, address) 

Client:

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 + " " + pings + " "+ elapsed        

    #If data is not received back from server, print it has timed out  
    except timeout:
        print 'REQUEST TIMED OUT'

    pings = pings - 1

Solution

  • I tested your code, and it works as expected on my machine. Your issue might not be your code. It could be a firewall or something else blocking all the packets on the loopback interface (127.0.0.1). Depending on your operating system, try testing with a packet monitor like Wireshark.

    Also, here are a few suggestions on how to improve your code to be more Pythonic:

    Server

    import random
    import socket
    
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    server_socket.bind(('', 12000))
    
    while True:
        rand = random.randint(0, 10)
        message, address = server_socket.recvfrom(1024)
        message = message.upper()
        if rand >= 4:
            server_socket.sendto(message, address)
    

    Client

    import time
    import socket
    
    for pings in range(10):
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        client_socket.settimeout(1.0)
        message = b'test'
        addr = ("127.0.0.1", 12000)
    
        start = time.time()
        client_socket.sendto(message, addr)
        try:
            data, server = client_socket.recvfrom(1024)
            end = time.time()
            elapsed = end - start
            print(f'{data} {pings} {elapsed}')
        except socket.timeout:
            print('REQUEST TIMED OUT')