2011-08-24 10 views
32

Z testu doszedłem do wniosku, że w kolejnych trzech przypadkach zwróci się socket.recv(recv_size).Kiedy wraca plik socket.recv (recv_size)?

  1. Po zamknięciu połączenia. Na przykład po stronie klienta o nazwie socket.close() lub wystąpił jakikolwiek błąd gniazda, zwrócony zostanie pusty ciąg znaków .

  2. Niektóre dane pochodzą, wielkość danych jest większa niż recv_size.

  3. Niektóre dane przychodzą, rozmiar danych jest mniejszy niż recv_size, a po krótkim czasie nie pojawiają się żadne dane (stwierdziłem, że 0.1s zadziała).

Więcej szczegółów na temat # 3:

#server.py 

while True: 
    data = sock.recv(10) 
    print data, 'EOF' 

#client1.py 

sock.sendall("12345") 
sock.sendall("a" * 50) 

#client2.py 

sock.sendall("12345") 
time.sleep(0.1) 
sock.sendall("a" * 50) 

Kiedy biegnę client1.py, że server.py Echos:

12345aaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaa EOF 

Kiedy biegnę client2.py, że server.py Echos:

12345 EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 

Czy moje wnioski są prawidłowe? Gdzie mogę zobaczyć oficjalny opis nr 3?

+0

http://docs.python.org/library/socket.html#socket.socket.recv – mouad

+7

Dzięki, ale podręcznik nie odpowiedział na moje pytanie. – redice

+3

Co powiecie tutaj: http://linux.die.net/man/2/recv – mouad

Odpowiedz

18

Tak, Twój wniosek jest poprawny. socket.recv to połączenie blokujące.

socket.recv(1024) odczytuje co najwyżej 1024 bajty, blokując, jeśli żadne dane nie czekają na odczyt. Jeśli nie odczytasz wszystkich danych, inne połączenie z numerem socket.recv nie zostanie zablokowane.

socket.recv będzie również kończyć się pustym łańcuchem, jeśli połączenie zostanie zamknięte lub wystąpi błąd.

Jeśli chcesz mieć gniazdo bez blokady, możesz użyć modułu wyboru (nieco bardziej skomplikowanego niż tylko używanie gniazd) lub możesz użyć socket.setblocking.

W przeszłości miałem problemy z socket.setblocking, ale możesz je wypróbować, jeśli chcesz.

+0

Nie widziałem żadnego oficjalnego opisu mojego wniosku 3). – redice

+0

socket.recv odczyta, co jest gotowe do odczytania, gdy zostanie wykonane wywołanie recv. Nie ma znaczenia, czy odczytana ilość jest mniejsza niż maksymalny rozmiar, gniazdo odblokuje się, gdy tylko będzie mogło odczytać dane. – Martin

+1

Możesz również wywołać recv() jako niezablokowanie, jeśli podasz odpowiednią flagę: 'socket.recv (10240, 0x40) # 0x40 = MSG_DONTWAIT aka O_NONBLOCK' Pamiętaj, że musisz złapać ' [Errno 11 ] Zasoby tymczasowo niedostępne " wyjątki, gdy nie ma danych wejściowych. – Ray

4

Będzie to miało to samo zachowanie, co wywołanie recv libc, patrz man page, aby uzyskać oficjalny opis zachowania (lub przeczytaj więcej general description interfejsu gniazd).