Как определить, что сервер закрывает сокет домена unix?

Я возился с искажённой библиотекой python, и я не могу понять, как заставить моего клиента обнаруживать, что сервер закрывает свой сокет. Мой клиент продолжает разрешать мне отправлять данные на несуществующий сервер. Вот мой сервер:

test_server.py

from twisted.internet import protocol, reactor, endpoints, stdio
from twisted.protocols.basic import LineReceiver


class ConnectionProtocol(LineReceiver):
    from os import linesep as delimiter

    def lineReceived(self, line):
        print 'got line: %s' % line
        self.sendLine(line)


class ConnectionFactory(protocol.Factory):
    def buildProtocol(self, addr):
        return ConnectionProtocol()


def main():
    endpoint = endpoints.UNIXServerEndpoint(reactor, './test.sock',  5, 0777, False)
    endpoint.listen(ConnectionFactory())
    print 'starting the reactor'
    reactor.run()


main()

Все, что он делает, это отправляет каждую полученную строку обратно подключающемуся клиенту. Вот клиент:

test_client.py

import os
from twisted.internet import protocol, reactor, endpoints, stdio
from twisted.protocols.basic import LineReceiver


class CommandProtocol(protocol.Protocol):
    def dataReceived(self, data):
        print data,


class StdinProtocol(LineReceiver):
    from os import linesep as delimiter

    def __init__(self, client):
        self._client = client

    def connectionMade(self):
        self.transport.write('>>> ')

    def lineReceived(self, line):
        print 'writing line: %s' % line
        self._client.transport.write(line + os.linesep)


def printError(failure):
    print str(failure)


def main():
    point = endpoints.UNIXClientEndpoint(reactor, './test.sock')
    proto = CommandProtocol()
    d = endpoints.connectProtocol(point, proto)
    d.addErrback(printError)

    stdio.StandardIO(StdinProtocol(proto))
    reactor.run()


main()

Если я запускаю сервер, а затем клиент, а затем убиваю сервер, клиент все равно пишет в транспорт CommandProtocol, как будто ничего не произошло. Я думал, что функция errback хоть что-то сообщит. В случае, когда клиент запускается перед сервером, функция errback вызывается с ошибкой ConnectError, но я специально ищу ситуацию, когда клиент уже подключился к серверу, а сервер завершает работу.

Как определить, что сервер выключен?


person Brian Schlenker    schedule 13.06.2014    source источник


Ответы (2)


ITransport.write является молчаливым отсутствием операций, если вызывается на транспорте, который был отключен.

Если вы хотите узнать, что соединение было потеряно, переопределите метод connectionLost. Как только вы узнаете, что соединение было потеряно, вы можете сделать так, чтобы ваша программа перестала принимать входные данные или сделала что-то еще с полученными входными данными.

person Jean-Paul Calderone    schedule 14.06.2014

Я думаю, что метод os.stat и модуль stat могут вам помочь. Можете ли вы изменить свои клиентские коды, как показано ниже:

import os
import stat
from twisted.internet import protocol, reactor, endpoints, stdio
from twisted.protocols.basic import LineReceiver


class CommandProtocol(protocol.Protocol):
    def dataReceived(self, data):
        print data,


class StdinProtocol(LineReceiver):
    from os import linesep as delimiter

    def __init__(self, client):
        self._client = client

    def connectionMade(self):
        self.transport.write('>>> ')

    def lineReceived(self, line):
        print 'writing line: %s' % line
        self._client.transport.write(line + os.linesep)


def printError(failure):
    print str(failure)


def main():
    if os.stat('./test.sock').st_mode & (stat.S_IRGRP | stat.S_IRUSR | stat.S_IROTH):
        print "1"
        print "using control socket"
        point = endpoints.UNIXClientEndpoint(reactor, './test.sock')

        proto = CommandProtocol()
        d = endpoints.connectProtocol(point, proto)
        d.addErrback(printError)

        stdio.StandardIO(StdinProtocol(proto))
        reactor.run()
    else:
        print "not ready"


main()
person nyzsirt    schedule 13.06.2014
comment
Это подходит для случая, когда клиент запускается раньше сервера, но не помогает в случае, когда сервер закрывается после того, как клиент уже подключился. Я отредактировал свой вопрос, чтобы уточнить этот момент. - person Brian Schlenker; 14.06.2014