Je suis nouveau sur python et sockets et j'essaie d'écrire un socket client/serveur en écho. J'ai écrit le serveur pour que 30% des paquets soient perdus. J'ai programmé mon client pour timeout après une seconde car le paquet pourrait être perdu. Cependant, chaque fois que j'exécute mon socket client, ma sortie est 100% REQUEST TIMED OUT. Je suppose que j'obtiens cette sortie car mon serveur ne reçoit jamais le message. J'ai regardé mon code plusieurs fois et je n'arrive pas à comprendre pourquoi j'obtiens constamment cette sortie. Voici mon code pour mon serveur et mes sockets client. Toute aide serait appréciée.
Socket de serveur:
# 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)
Prise 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
J'ai testé votre code et il fonctionne comme prévu sur ma machine. Votre problème n'est peut-être pas votre code. Ce pourrait être un pare-feu ou autre chose bloquant tous les paquets sur l'interface de bouclage (127.0.0.1). En fonction de votre système d'exploitation, essayez de tester avec un moniteur de paquets comme Wireshark.
En outre, voici quelques suggestions sur la façon d'améliorer votre code pour être plus Pythonic:
Serveur
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')
Voici une alternative avec 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()