Giả sử bạn đang sử dụng mô-đun ổ cắm tiêu chuẩn, bạn nên bắt gặp ngoại lệ socket.error: (32, 'Broken pipe')
(không phải IOError như những người khác đã đề xuất). Điều này sẽ được nêu ra trong trường hợp bạn đã mô tả, tức là gửi/ghi vào một ổ cắm mà phía xa đã bị ngắt kết nối.
import socket, errno, time
# setup socket to listen for incoming connections
s = socket.socket()
s.bind(('localhost', 1234))
s.listen(1)
remote, address = s.accept()
print "Got connection from: ", address
while 1:
try:
remote.send("message to peer\n")
time.sleep(1)
except socket.error, e:
if isinstance(e.args, tuple):
print "errno is %d" % e[0]
if e[0] == errno.EPIPE:
# remote peer disconnected
print "Detected remote disconnect"
else:
# determine and handle different error
pass
else:
print "socket error ", e
remote.close()
break
except IOError, e:
# Hmmm, Can IOError actually be raised by the socket module?
print "Got IOError: ", e
break
Lưu ý rằng ngoại trừ điều này sẽ không luôn luôn được nâng lên trên ghi đầu tiên vào một ổ cắm đóng cửa - thường càng ghi giây (trừ số byte ghi trong ghi đầu tiên là lớn hơn so với kích thước bộ đệm của ổ cắm). Bạn cần ghi nhớ điều này trong trường hợp ứng dụng của bạn nghĩ rằng đầu cuối từ xa nhận được dữ liệu từ lần ghi đầu tiên khi nó có thể đã bị ngắt kết nối.
Bạn có thể giảm tỷ lệ (nhưng không hoàn toàn loại bỏ) điều này bằng cách sử dụng select.select()
(hoặc poll
). Kiểm tra dữ liệu đã sẵn sàng để đọc từ peer trước khi thử viết. Nếu select
báo cáo rằng có sẵn dữ liệu để đọc từ ổ cắm ngang hàng, hãy đọc nó bằng cách sử dụng socket.recv()
. Nếu điều này trả về một chuỗi rỗng, từ xa ngang hàng đã đóng kết nối. Bởi vì vẫn còn một điều kiện chủng tộc ở đây, bạn vẫn sẽ cần phải nắm bắt và xử lý các ngoại lệ.
Xoắn là điều tuyệt vời cho loại điều này, tuy nhiên, có vẻ như bạn đã viết một chút mã công bằng.
Nếu tôi thử: #something ngoại trừ: #anything, nó sẽ chỉ bắt bất cứ điều gì, và không chỉ IOErrors? –
Chăn ngoại trừ một chính sách xấu. Tuy nhiên, nó sẽ bắt bất kỳ loại ngoại lệ. Bạn biết đó là một IOError. Xử lý điều đó. Nếu một cái gì đó khác cây trồng lên, tìm ra lý do tại sao và xử lý nó một cách thích hợp. Bạn không muốn che dấu các lỗi như phân chia bằng không hoặc hết bộ nhớ. –
Nếu bạn đang sử dụng mô-đun socket của Python, bạn sẽ không nhận được một ngoại lệ IOError: bạn sẽ nhận được một ngoại lệ socket.error. – mhawke