如何检测关闭unix域套接字的服务器?

时间:2014-06-13 20:38:20

标签: python sockets twisted unix-socket

我正在搞乱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函数至少会报告一些内容。在客户端在服务器之前运行的情况下,使用ConnectError调用errback函数,但我特别希望检测客户端已连接到服务器的情况,并且服务器退出。

如何检测服务器是否已关闭?

2 个答案:

答案 0 :(得分:2)

ITransport.write如果在已断开连接的传输上调用,则为无声操作。

如果您想了解连接丢失,请覆盖connectionLost方法。一旦您知道连接已丢失,您可以安排程序停止接受输入或使用收到的输入执行其他操作。

答案 1 :(得分:-2)

我猜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()