如何检测服务器关闭Unix域套接字?
我正在玩一个叫做Python的twisted库,但我不知道怎么让我的客户端检测到服务器关闭了它的连接。我的客户端还是可以继续向这个不存在的服务器发送数据。下面是我的服务器代码:
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
函数会因为连接错误而被调用,但我特别想检测的是客户端已经连接到服务器后,服务器退出的情况。
我该怎么才能检测到服务器已经关闭了呢?
2 个回答
-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()
2
ITransport.write
在连接断开时调用是没有任何反应的,也就是不会做任何事情。
如果你想知道连接是否丢失,可以重写 connectionLost
这个方法。一旦你知道连接已经断开,你就可以让你的程序停止接收输入,或者对收到的输入做其他处理。