2012-03-25 23 views
10

Estoy tratando de escribir un programa de eco cliente/servidor básico, para probar el uso de temporizadores para la retransmisión basada en select() (aunque tuve que comentar ese bit para simplificar la depuración cuando no estaba funcionando como estaba previsto). Éstos son fragmentos de código relevante:Python UDP cliente/servidor programa, problemas

Servidor:

from socket import * 
import sys 
import select 
address = ('localhost', 6005) 
server_socket = socket(AF_INET, SOCK_DGRAM) 
server_socket.bind(address) 

while(1): 
    print "Listening" 
    recv_data, addr = server_socket.recvfrom(2048) 
    print recv_data 
    if recv_data == "Request 1" : 
     print "Received request 1" 
     server_socket.sendto("Response 1", address) 
    elif recv_data == "Request 2" : 
     print "Received request 2" 
     data = "Response 2" 
     server_socket.sendto(data, address) 

Cliente:

from socket import * 
import sys 
import select 

address = ('localhost', 6005) 
client_socket = socket(AF_INET, SOCK_DGRAM) 

num_retransmits = 0 
while(num_retransmits < 60): 
    num_retransmits = num_retransmits + 1 


    data = "Request 1" 
    client_socket.sendto(data, address) 
    print "Sending request 1" 

    recv_data, addr = client_socket.recvfrom(2048) 

    print recv_data, "!!" 

La salida en el cliente es simplemente 'Envío de una orden 1', y cuando se utiliza en un punto de interrupción cualquier cosa en la llamada de recvfrom o debajo de ella, no llega al punto de interrupción. Entonces me imagino que el cliente no está recibiendo nada y espera hasta que lo haga. Por otro lado, la salida en el servidor es:

  • Escuchar
  • Solicitud 1
  • petición recibida 1
  • Escuchar
  • Respuesta 1

y así sucesivamente y así adelante

Después del primer ciclo, el servidor realiza un bucle de nuevo y p Notas RESPUESTA 1. Esto significa que lo que hizo el servidor fue recibir la solicitud 1, enviar la respuesta 1 al cliente, el bucle ... pero después de que se repita la segunda vez, ¡la respuesta 1 está STILL en su zócalo! Es por eso que cuando imprime recv_data, imprime la respuesta 1. Por otro lado, el cliente no está imprimiendo recv_data, porque el cliente no lo ha recibido, todavía está en el búfer del socket del servidor.

Por favor, ayuda - He intentado buscar en otros programas de eco pero todos parecen usar TCP y son bastante sencillos (y creo que he seguido los mismos pasos). No tengo idea de por qué mi programa UDP no funciona. Intenté mirar la llamada a sendall() pero parece que solo funciona para TCP.

Respuesta

14

Tienes que enviar a addr en lugar de dirección.

from socket import * 
import sys 
import select 
address = ('localhost', 6005) 
server_socket = socket(AF_INET, SOCK_DGRAM) 
server_socket.bind(address) 

while(1): 
    print "Listening" 
    recv_data, addr = server_socket.recvfrom(2048) 
    print recv_data 
    if recv_data == "Request 1" : 
     print "Received request 1" 
     server_socket.sendto("Response 1", addr) 
    elif recv_data == "Request 2" : 
     print "Received request 2" 
     data = "Response 2" 
     server_socket.sendto(data, addr) 
+0

¡Gracias! Por alguna razón, esta publicación no apareció: S Pero sí, eso lo solucionó – misaochan

1

tal vez la línea 10 en el lado servidor

recv_data, addr = server_socket.recvfrom (2048)

debería ser

recv_data, addr = server_socket.sendto (2048)

?

ps> Im a noob. = P

+4

Gracias. Aprendí más tratando de responderte que cualquier cosa que puedas obtener de mí. –

2

Lo que está sucediendo aquí es que el servidor está enviando 'Response 1' a localhost:6005, y luego lo recibe inmediatamente ya que también está escuchando en localhost:6005.

El servidor se enlaza y escucha en su (address, port), como es correcto. Cuando el cliente se conecta sin vincular primero, se le asigna automáticamente un (address, port) sin usar.Necesitará determinar qué (address, port) el cliente está utilizando para responder a él, ya sea por bind para establecer explícitamente un (address, port) conocido, o mediante el addr devuelto por recvfrom.

+0

Gracias, yo también estaba pensando así. Sin embargo, seguramente esta es la única forma de probar tanto el servidor como el cliente en la misma máquina: vincular el servidor al puerto A y 'localhost'; luego, usar el cliente para enviar cosas al puerto A y al servidor local. Can bind() también se puede usar para clientes? – misaochan

+0

¡Oh, gracias! Todo está arreglado ahora. Por alguna razón, tenía la impresión de que el servidor y el cliente tenían que estar usando los mismos puertos en el host local ... – misaochan

+0

@JosephineLim Bind se puede usar en los sockets de los clientes, pero no es común. – ephemient