Search code examples
pythonsocketstwistedunix-socket

How to detect the server closing a unix domain socket?


I'm messing around with the python twisted library, and I can't seem to figure out how to get my client to detect a server closing its socket. My client continues to let me send data to the non existent server. Here is my server:

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

All it does is send each line it gets back to the connecting client. Here is the client:

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

If I run the server and then the client, and then kill the server, the client still writes to the CommandProtocol's transport like nothing happened. I thought the errback function would at least report something. In the case where the client is run before the server, the errback function is called with a ConnectError, but I'm specifically looking to detect the situation where the client has already connected to a server, and the server exits.

How can I detect that the server has shutdown?


Solution

  • ITransport.write is a silent no-op if called on a transport that has been disconnected.

    If you want to learn that a connection was lost, override the connectionLost method. Once you know that the connection has been lost you can arrange for your program to stop accepting input or do something else with the input it receives.