2013-06-30 6 views
13

Tôi đang viết một ứng dụng bằng Python 2.7.5 bằng giao diện ổ cắm nguyên (import socket).Python: phát hiện khi một ổ cắm ngắt kết nối vì bất kỳ lý do gì?

Tôi cần biết nếu có cách nào tôi có thể đăng ký một số loại sự kiện hoặc dễ dàng kiểm tra ở khoảng thời gian thông thường, nếu kết nối cổng TCP vẫn được kết nối và thiết lập.

Hầu hết các lời khuyên tôi đã tìm thấy đều nói những điều như "chỉ cố đọc từ nó; nếu đóng cửa, bạn sẽ gặp lỗi hoặc không có byte". Tuy nhiên, đôi khi tôi chưa sẵn sàng để read từ nó nhưng tôi vẫn muốn biết nếu các ổ cắm được đóng lại, vì vậy ví dụ tôi có thể tự kết nối lại ngay lập tức.

Ngoài ra, read ing từ ổ cắm sẽ loại bỏ các byte đọc từ bộ đệm, do đó, read ing chỉ đơn giản là để kiểm tra kết nối "liveness" dường như không khả thi.

Có một chuỗi nền để kiểm tra độ kết nối sẽ là OK với tôi. Chủ đề đó có thể kiểm tra nói một lần mỗi giây để xem kết nối có đang hoạt động hay không; nếu nó bị xóa, thì nó có thể gọi một hàm, hoặc thiết lập một biến hoặc một số thứ khác để ứng dụng biết kết nối đã đóng. Biết TẠI SAO nó đóng lại (thiết lập lại bởi peer, timeout, vv) sẽ hữu ích hơn nữa ....

Bất kỳ lời khuyên nào về điều này?

+0

trên Posix; sử dụng 'select()' (hoặc 'epoll()' cho Linux) – tMC

+0

Related: http://stackoverflow.com/questions/17705239/is-there-a-way-to-detect-that-tcp-socket-has -Được đóng-by-the-remote-peer-wit (TL; DR: không có cách nào tốt để tìm hiểu xem kết nối đã bị đóng chưa trừ khi bạn sẵn sàng đọc tất cả các byte đến từ socket trước; Các cổng TCP được thực hiện theo cách cố ý bởi vì chúng được dựa trên ý tưởng đặt hàng sự kiện FIFO, nghĩa là chúng muốn bạn đọc dữ liệu đến theo thứ tự và chỉ tìm hiểu về cuối luồng sau khi bạn đọc tất cả) –

Trả lời

13

Sử dụng select như hướng dẫn này đề nghị http://docs.python.org/2/howto/sockets.html#non-blocking-sockets

Nếu một ổ cắm là trong đầu ra danh sách có thể đọc được, bạn có thể lên-gần-to-số-như-chúng tôi chưa từng có-get-in-này -doanh nghiệp mà một recv trên ổ cắm đó sẽ trả về một cái gì đó. Cùng một ý tưởng cho danh sách có thể ghi. Bạn sẽ có thể gửi một cái gì đó. Có lẽ không phải tất cả các bạn muốn, nhưng cái gì là tốt hơn không có gì. (Trên thực tế, bất kỳ ổ cắm nào hợp lý sẽ trở lại dưới dạng có thể ghi được - nó chỉ có nghĩa là vùng bộ đệm mạng bên ngoài khả dụng.)

... nếu ở đâu đó trong danh sách đầu vào ổ cắm đó là cái chết. Thất bại.

Đây là dòng Tôi thường sử dụng

import select 
import socket 

ip = '127.0.0.1' 
port = 80 

conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
conn.connect((ip, port)) 

while True: 
    try: 
     ready_to_read, ready_to_write, in_error = \ 
      select.select([conn,], [conn,], [], 5) 
    except select.error: 
     conn.shutdown(2) # 0 = done receiving, 1 = done sending, 2 = both 
     conn.close() 
     # connection error event here, maybe reconnect 
     print 'connection error' 
     break 
    if len(ready_to_read) > 0: 
     recv = conn.recv(2048) 
     # do stuff with received data 
     print 'received:', recv 
    if len(ready_to_write) > 0: 
     # connection established, send some stuff 
     conn.send('some stuff')