2012-03-25 9 views
10

Próbuję napisać podstawowy program echo klienta/serwera, aby przetestować użycie timerów do retransmisji w oparciu o select() (chociaż musiałem skomentować ten bit, aby uprościć debugowanie kiedy nie działało zgodnie z przeznaczeniem). Oto fragmenty z odpowiednim kodem:Program klienta/serwera Python UDP, problemy

Serwer:

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) 

Klient:

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, "!!" 

Wyjście na kliencie jest po prostu „Wysyłanie żądania 1”, a gdy punkt przerwania jest stosowana cokolwiek na lub poniżej wywołania recvfrom, nie osiąga punktu przerwania. Tak więc myślę, że klient nie otrzymuje niczego i trzyma się aż do tego. Z drugiej strony, wyjście na serwerze jest:

  • Słuchanie
  • Zapytanie 1
  • odebrane żądanie 1
  • Słuchanie
  • reakcji 1

i tak dalej i tak naprzód

Po pierwszej pętli, serwer ponownie wykona pętle i p rints ODPOWIEDŹ 1. Oznacza to, że tym, co zrobił serwer, było odebranie żądania 1, wysłanie odpowiedzi 1 do klienta, pętla ... ale po tym jak pętle po raz drugi, odpowiedź 1 jest STILL w swoim gnieździe! Dlatego, gdy drukuje recv_data, drukuje odpowiedź 1. Z drugiej strony, klient nie drukuje recv_data, ponieważ klient go nie otrzymał - nadal znajduje się w buforze gniazda serwera.

Proszę o pomoc - próbowałem przeglądać inne programy echo, ale wszystkie wydają się używać TCP i są dość proste (i myślę, że podążałem tymi samymi krokami). Nie mam pojęcia, dlaczego mój program UDP nie działa. Próbowałem spojrzeć na wywołanie sendall(), ale wydaje się, że działa tylko dla TCP.

Odpowiedz

14

Musisz wysłać do adresu zamiast adresu.

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

Dziękujemy! Z jakiegoś powodu ten post nie pojawił się: S Ale tak, to naprawiło – misaochan

1

może linii 10 po stronie serwera

recv_data, adres = server_socket.recvfrom (2048)

należy

recv_data, adres = server_socket.sendto (2048)

?

ps> Im a noob. = P

+4

Dzięki. Nauczyłem się więcej próbować odpowiedzieć, niż cokolwiek, co można uzyskać ode mnie. –

2

To, co się tutaj dzieje, to serwer wysyłający 'Response 1' do localhost:6005, a następnie od razu go odbiera, ponieważ również nasłuchuje na localhost:6005.

Serwer wiąże się i nasłuchuje na swoim (address, port), ponieważ jest poprawny. Gdy klient łączy się bez wiązania jako pierwszy, jest automatycznie przypisywany nieużywanemu (address, port).Musisz określić, jakiego klienta używa klient, aby odpowiedzieć na nie - albo przez bind, aby jawnie ustawić znaną (address, port), albo używając addr zwróconego przez recvfrom.

+0

Dzięki, tak też myślałem. Jednak na pewno jest to jedyny sposób na przetestowanie zarówno serwera, jak i klienta na tym samym komputerze - należy połączyć serwer z portem A i "localhost", a następnie użyć klienta do wysłania rzeczy do Port A i localhost? Czy funkcja bind() może być również używana dla klientów? – misaochan

+0

Och, dziękuję! Teraz wszystko jest już naprawione. Z jakiegoś powodu odniosłem wrażenie, że zarówno serwer, jak i klient muszą korzystać z tych samych portów na localhost ... – misaochan

+0

@JosephineLim Bind może być używany na gniazdach klienta, ale jest to rzadkie. – ephemient