2011-08-24 23 views
32

Từ thử nghiệm, tôi kết luận rằng trong ba trường hợp sau, socket.recv(recv_size) sẽ trả về.Khi nào socket.recv (recv_size) trả về?

  1. Sau khi đóng kết nối. Ví dụ, phía máy khách được gọi là socket.close() hoặc bất kỳ lỗi socket nào xảy ra, nó sẽ trả về chuỗi rỗng.

  2. Một số dữ liệu đến, kích thước của dữ liệu là hơn recv_size.

  3. Một số dữ liệu đến, kích thước của dữ liệu ít hơn recv_size và không có nhiều dữ liệu hơn đến sau một thời gian ngắn (tôi thấy 0.1s sẽ làm việc).

Thông tin chi tiết về # 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) 

Khi tôi chạy client1.py, các server.py echos:

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

Khi tôi chạy client2.py, các server.py echos:

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

Kết luận của tôi có đúng không? Tôi có thể xem mô tả chính thức về số 3 ở đâu?

+0

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

+7

Cảm ơn, nhưng hướng dẫn không trả lời câu hỏi của tôi. – redice

+3

Làm thế nào về ở đây: http://linux.die.net/man/2/recv – mouad

Trả lời

18

Có, kết luận của bạn là chính xác. socket.recv là cuộc gọi chặn.

socket.recv(1024) sẽ đọc nhiều nhất là 1024 byte, ngăn chặn nếu không có dữ liệu đang chờ để được đọc. Nếu bạn không đọc tất cả dữ liệu, một cuộc gọi khác đến socket.recv sẽ không chặn.

socket.recv cũng sẽ kết thúc với một chuỗi rỗng nếu kết nối được đóng cửa hoặc có lỗi.

Nếu bạn muốn có ổ cắm không chặn, bạn có thể sử dụng mô-đun chọn (phức tạp hơn một chút so với chỉ sử dụng ổ cắm) hoặc bạn có thể sử dụng socket.setblocking.

tôi có vấn đề với socket.setblocking trong quá khứ, nhưng cảm thấy tự do để thử nó nếu bạn muốn.

+0

Tôi không thấy bất kỳ mô tả chính thức nào về kết luận của tôi 3). – redice

+0

socket.recv sẽ đọc những gì đã sẵn sàng để được đọc khi thực hiện cuộc gọi đến recv. Nó không quan trọng nếu số tiền đọc là ít hơn kích thước tối đa, các ổ cắm sẽ bỏ chặn ngay sau khi nó có thể đọc dữ liệu. – Martin

+1

Bạn cũng có thể gọi recv() là không chặn nếu bạn cung cấp cờ phù hợp cho nó: 'socket.recv (10240, 0x40) # 0x40 = MSG_DONTWAIT aka O_NONBLOCK' Xin lưu ý rằng bạn phải nắm bắt ' [Errno 11 ] Tài nguyên tạm thời không khả dụng' ngoại lệ khi không có dữ liệu đầu vào. – Ray

4

Nó sẽ có hành vi tương tự như cuộc gọi recv libc bên dưới, xem man page để biết mô tả chính xác về hành vi (hoặc đọc thêm general description của socket api).

Các vấn đề liên quan