项目中遇到问题:在客户端与服务器端正常连接时拔掉网线也就相当于把连接强行断开,此时客户端就会出现该错误:
[WinError 10054] 远程主机强迫关闭了一个现有的连接。
此时要进行处理就需要先找到切入点,此时的切入点就是找到抛出异常的位置,在异常处理中处理此部分问题,异常处理可不是简单的打印异常就可以了啊!
class socketCreateStoppable(threading.Thread):
"""Thread class with a stop() method. The thread itself has to check
regularly for the stopped() condition."""
def __init__(self,server_ip, server_port,macNumA,macNumB,distanceListA,distanceListB,timestrapListA,timestrapListB):
super(socketCreateStoppable, self).__init__()
self._stop_event = threading.Event()
#print('server_ip',server_ip_list)
#print(time.localtime(time.time()))
self.server_ip = server_ip
self.server_port = server_port
self.tcp_client = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
self.macNumA = macNumA
self.macNumB = macNumB
self.distanceListA = distanceListA
self.distanceListB = distanceListB
self.timestrapListA = timestrapListA
self.timestrapListB = timestrapListB
def stop(self):
#print(time.time())
print('#'*20)
self._stop_event.set()
self.tcp_client.close() # 在停止的时候将tcp_client关掉
print(time.time(),'stop success')
logging.warning('stop success')
def stopped(self):
return self._stop_event.is_set()
def run(self):
# print("running",threading.Thread.getName(self))
logging.debug("%s is start,server ip is %s,server port is %d" %(threading.Thread.getName(self),self.server_ip,self.server_port))
# Thread-3elf.args is stop;the reason is check 404 by checkSelf
while True:
try:
# self.tcp_client.settimeout(10)
# print("self addr is:",self.server_port,self.server_ip)
self.tcp_client.connect((self.server_ip, self.server_port))
# print('server_ip:', self.server_ip)
while True:
# 3.收发
recv_content = self.tcp_client.recv(1024)
#print(type(recv_content))
self.dataList = list(recv_content)
#print(self.dataList)
self.check_struct()
except Exception as e:
print(e)
logging.error(e)
self.tcp_client.close()
self.stop()
#time.sleep(2)
time.sleep(1)
if self.stopped():
break
def check_struct(self):
# numA代表A的mac码 numB代表B的mac码
# distanceListA与B分别代表当前基站与距离AB标签的距离
# timestrapList代表是写AB时的时间戳,如果有某一个时间戳不更新了,会给其赋值一个很大的数
if len(self.dataList) == 23:
if self.dataList[0] == 170 and self.dataList[2] == 17 and self.dataList[-1] == 126:
macList = self.dataList[3:9]
length = (self.dataList[18] * 256 + self.dataList[19]) * 0.01
if macList == self.macNumA:
self.distanceListA.append(length)
self.timestrapListA.append(time.time())
#print()
elif macList == self.macNumB:
self.distanceListB.append(length)
self.timestrapListB.append(time.time())
else:
print('mac is error')
else:
print('information error')
#print(1)
elif len(self.dataList) == 0:
print('connected is disconnecting')
self.tcp_client.close()
self.stop()
# 自毁程序,如果检测到一直为404,将本线程杀死
def checkSelf(self):
self.numListA = self.distanceListA[-5:]
self.numListB = self.distanceListB[-5:]
self.avgA = sum(self.numListA)/len(self.numListA)
self.avgB = sum(self.numListB)/len(self.numListB)
if abs(self.avgA-404)<1 or abs(self.avgB-404)<1:
logging.warning("%s is stop;the reason is check 404 by checkSelf" %threading.Thread.getName(self))
self.tcp_client.close()
self.stop()
其中用到的TCP客户端亦然是可以stop的线程实现的,可以在检测到异常之后关掉本线程,在外面通过另一个线程检测,当发现该端口已经关闭时再重新起一个线程连接TCP服务器,IP和PORT和当前的线程一样,这样就解决了。
在进行线程重启时必须要做到的是在关闭线程前把该连接关掉 即:self.tcp_client.close()