Python socket 连接异常
我正在进行一个套接字连接的操作,想要改善异常处理,但遇到了困难。每当我用一个无效的参数调用 socket.connect(server_address)
时,程序就会停止,但似乎并没有抛出异常。以下是我的代码:
import socket
import sys
import struct
class ARToolkit():
def __init__(self):
self.x = 0
self.y = 0
self.z = 0
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.logging = False
def connect(self,server_address):
try:
self.sock.connect(server_address)
except socket.error, msg:
print "Couldnt connect with the socket-server: %s\n terminating program" % msg
sys.exit(1)
def initiate(self):
self.sock.send("start_logging")
def log(self):
self.logging = True
buf = self.sock.recv(6000)
if len(buf)>0:
nbuf = buf[len(buf)-12:len(buf)]
self.x, self.y, self.z = struct.unpack("<iii", nbuf)
def stop_logging(self):
print "Stopping logging"
self.logging = False
self.sock.close()
这个类可能看起来有点奇怪,但它是用来接收来自另一台运行ARToolKit的计算机的坐标。无论如何,问题出在 connect()
函数上:
def connect(self,server_address):
try:
self.sock.connect(server_address)
except socket.error, msg:
print "Couldnt connect with the socket-server: %s\n terminating program" % msg
sys.exit(1)
如果我用一个随机的IP地址和端口号调用这个函数,整个程序就会在这一行停止:
self.sock.connect(server_address)
我读过的文档上说,如果出现错误,它会抛出一个socket.error异常。我也试过直接用:
except Exception, msg:
如果我没记错的话,这样可以捕获任何异常,但结果仍然没有。非常感谢能得到帮助。另外,当出现不想要的异常时,使用sys.exit退出程序可以吗?
谢谢
2 个回答
你最后提到的通用异常问题在于冒号的位置。冒号应该放在整个异常的后面,而不是放在except语句后面。所以,要捕获所有异常,你需要这样写:
except Exception,msg:
不过从Python 2.6版本开始,你应该使用as语句,而不是用逗号,像这样:
except Exception as msg:
我运行代码的时候没有问题(注意你需要在连接方法中传入一个元组)。如果你想专门捕获socket错误,那么你需要捕获socket.error
这个类。就像你写的那样:
except socket.error as msg:
如果你想确保输入的是一个元组,可以再加一个异常循环:
except socket.error as msg:
print "Socket Error: %s" % msg
except TypeError as msg:
print "Type Error: %s" % msg
如果你选择了一个随机但有效的IP地址和端口,socket.connect()
会尝试连接到这个地址。默认情况下,如果没有为这个连接设置明确的超时时间,它会在连接时一直等待,最后会超时,并抛出一个错误,内容是socket.error: [Errno 110] Connection timed out
。
在我的电脑上,默认的超时时间是120秒。也许你没有等够长的时间,让socket.connect()
返回结果(或者超时)?
你可以尝试像这样减少超时时间:
import socket
s = socket.socket()
s.settimeout(5) # 5 seconds
try:
s.connect(('123.123.123.123', 12345)) # "random" IP address and port
except socket.error, exc:
print "Caught exception socket.error : %s" % exc
需要注意的是,如果为这个连接明确设置了超时时间,那么抛出的错误会是socket.timeout
,这个错误是从socket.error
派生出来的,因此会被上面的异常处理部分捕获。