I'm new to python and sockets and 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. Below is my code for my server and client sockets. Any help would be appreciated.
Server Socket:
 # 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 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 + " " + pings + " "+ elapsed        
    #If data is not received back from server, print it has timed out  
    except timeout:
        print 'REQUEST TIMED OUT'
    pings = pings - 1
                UDP - User Datagram Protocol sockets It is a connection-less protocol where you directly send packets without have to establish a proper connection. UDP packets have smaller headers compared to TCP headers. Also data communication is faster since no acknowledgement is exchanged for reliable packet delivery.
In UDP, the client does not form a connection with the server like in TCP and instead just sends a datagram. Similarly, the server need not accept a connection and just waits for datagrams to arrive. Datagrams upon arrival contain the address of the sender which the server uses to send data to the correct client.
The steps of establishing a UDP socket communication on the server side are as follows: Create a socket with the socket() function; Bind the socket to an address using the bind() function; Send and receive data by means of recvfrom() and sendto().
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')
                        Here is an alternative with asyncio.
import asyncio
import random
class EchoServerProtocol:
    def connection_made(self, transport):
        self.transport = transport
    def datagram_received(self, data, addr):
        message = data.decode()
        print('Received %r from %s' % (message, addr))
        rand = random.randint(0, 10)
        if rand >= 4:
            print('Send %r to %s' % (message, addr))
            self.transport.sendto(data, addr)
        else:
            print('Send %r to %s' % (message, addr))
            self.transport.sendto(data, addr)
loop = asyncio.get_event_loop()
print("Starting UDP server")
# One protocol instance will be created to serve all client requests
listen = loop.create_datagram_endpoint(
    EchoServerProtocol, local_addr=('127.0.0.1', 12000))
transport, protocol = loop.run_until_complete(listen)
try:
    loop.run_forever()
except KeyboardInterrupt:
    pass
transport.close()
loop.close()
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With