bst*_*rre 2 python sockets garbage-collection exception
我的类包含一个连接到服务器的套接字.该类的一些方法可以抛出异常.我正在运行的脚本包含一个外部循环,它捕获异常,记录错误,并创建一个尝试重新连接到服务器的新类实例.
问题是服务器一次只处理一个连接(按设计),并且"旧"套接字仍然连接.因此,新的连接尝试会挂起脚本.我可以通过强制关闭旧套接字解决这个问题,但我想知道:为什么套接字不会自动关闭?
当它"卡住"时,netstat显示连接到端口的两个插槽.服务器正在等待来自第一个套接字的输入,但它还没有处理新的套接字.
我在一个虚拟服务器上运行它,它向每个传入的行回复"error \n".
编辑:请参阅我对Mark Rushakoff的回答.在异常处理程序中的断言(False)[我随后捕获]似乎强制套接字关闭.
import socket
class MyException(Exception):
pass
class MyClient(object):
def __init__(self, port):
self.sock = socket.create_connection(('localhost', port))
self.sockfile = self.sock.makefile()
def do_stuff(self):
self._send("do_stuff\n")
response = self._receive()
if response != "ok\n":
raise MyException()
return response
def _send(self, cmd):
self.sockfile.write(cmd)
self.sockfile.flush()
def _receive(self):
return self.sockfile.readline()
def connect():
c = MyClient(9989)
# On the second iteration, do_stuff() tries to send data and
# hangs indefinitely.
print c.do_stuff()
if __name__ == '__main__':
for _ in xrange(3):
try:
connect()
except MyException, e:
print 'Caught:', e
# This would be the workaround if I had access to the
# MyClient object:
#c.sock.close()
#c.sockfile.close()
Run Code Online (Sandbox Code Playgroud)
编辑:这是(丑陋的)服务器代码:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
s.bind(('localhost', 9989))
s.listen(5)
(c,a) = s.accept()
f = c.makefile()
print f.readline()
f.write('error\n')
f.flush()
(c2,a) = s.accept()
f = c.makefile()
print f.readline()
s.close()
Run Code Online (Sandbox Code Playgroud)
这是垃圾收集的工件.即使对象超出范围,它也不一定被收集并因此被销毁,直到发生垃圾收集运行 - 这与C++不同,只要对象失去范围就会调用析构函数.
您可以通过更改connect为解决此特定问题
def connect():
try:
c = MyClient(9989)
# On the second iteration, do_stuff() tries to send data and
# hangs indefinitely.
print c.do_stuff()
finally:
c.sock.close()
c.sockfile.close()
Run Code Online (Sandbox Code Playgroud)
或者,您可以定义__enter__和__exit__for MyClient,并执行with语句:
def connect():
with MyClient(9989) as c:
print c.do_stuff()
Run Code Online (Sandbox Code Playgroud)
这与try-finally实际上是一样的.
| 归档时间: |
|
| 查看次数: |
517 次 |
| 最近记录: |