ловить сломанный сокет в питоне - PullRequest
2 голосов
/ 25 октября 2010

У меня проблемы с обнаружением сломанного сокета, когда возникает исключение сломанной трубы. Посмотрите код ниже для примера:

Сервер:

import errno, select, socket, time, SocketServer

class MetaServer(object):
    def __init__(self):
        self.server = Server(None, Handler, bind_and_activate=False)
    def run(self, sock, addr):
        rfile = sock.makefile('rb', 1)
        self.server.process_request(sock, addr)
        while 1:
            r, _, _ = select.select([rfile], [], [], 1.0)
            if r:
                print 'Got %s' % rfile.readline()
            else:
                print 'nothing to read'

class Server(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    allow_reuse_address = True
    daemon_threads = True

class Handler(SocketServer.StreamRequestHandler):
    def handle(self):
        print 'connected!'
        try:
            while 1:
                self.wfile.write('testing...')
                time.sleep(1)
        except socket.error as e:
            if e.errno == errno.EPIPE:
                print 'Broken pipe!'
        self.finish()
        self.request.close()

if __name__ == '__main__':
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('127.0.0.1', 8081))
    s.listen(5)
    ms = MetaServer()
    while 1:
        client, address = s.accept()
        ms.run(client, address)

Клиент:

import select, socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 8081))
while 1:
    r, _, _ = select.select([s], [], [], 1.0)
    if not r:
        continue
    msg = s.recv(1024)
    print 'Got %s' % (msg,)

Теперь, если я запускаю сервер и клиент, все в порядке, и я получаю сообщение "ничего не читается" каждую секунду. Как только я нажимаю CTRL-C на клиенте, сервер сходит с ума и начинает «читать» из того, что должно быть отключенным сокетом, сбрасывая много сообщений «Got».

Есть ли какой-нибудь способ обнаружить этот сломанный сокет в функции MetaServer.run(), чтобы избежать вышеуказанного поведения?

1 Ответ

3 голосов
/ 25 октября 2010

Да, это то, чего нет в документации, но старое поведение Un * x: вам нужно прервать, когда вы получите пустую строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...