python pyqt pyqt4 qtcpsocket

python - Pyqt; QTcpSocket siempre en connectingState después del reinicio del servidor;



pyqt4 (1)

Tengo una subclase de QTcpSocket. Y el problema es: cuando llegué al servidor, todo está bien, pero después de conectar el socket reinicio el servidor (python socketServer, simplemente cierro y comienzo el script de nuevo) desconectando el socket y tratando de reconectarme mientras el servidor está inactivo, pero cuando comienzo el servidor otra vez - No pasó nada, socket.state () siempre en ConnectingState ... ¿qué pasa?

Aquí código de ejemplo:

# -*- coding: utf-8 -*- from PyQt4.QtCore import QVariant, QTimer, pyqtSignal, QCoreApplication import sys from PyQt4.QtNetwork import QTcpSocket from re import match import json MAX_WAIT_LEN = 8 class UpQSocket(QTcpSocket): data_ready = pyqtSignal(unicode) def __init__(self): QTcpSocket.__init__(self) self.wait_len = '''' self.temp = '''' self.setSocketOption(QTcpSocket.KeepAliveOption, QVariant(1)) self.readyRead.connect(self.on_ready_read) self.connected.connect(self.on_connected) self.disconnected.connect(self.on_disconnect) self.error.connect(self.on_error) self.data_ready.connect(self.print_command) def connectToHost(self, host, port): print ''connectToHost'' self.temp = '''' self.wait_len = '''' QTcpSocket.abort(self) QTcpSocket.connectToHost(self, host, port) def close(self): print ''close!'' self.disconnectFromHost() def send(self, data): self.writeData(''%s|%s'' % (len(data), data)) def on_ready_read(self): if self.bytesAvailable(): data = str(self.readAll()) while data: if not self.wait_len and ''|'' in data:#new data and new message self.wait_len , data = data.split(''|'',1) if match(''[0-9]+'', self.wait_len) and (len(self.wait_len) <= MAX_WAIT_LEN) and data.startswith(''{''):#okay, this is normal length self.wait_len = int(self.wait_len) self.temp = data[:self.wait_len] data = data[self.wait_len:] else:#oh, it was crap self.wait_len , self.temp = '''','''' return elif self.wait_len:#okay, not new message, appending tl= int(self.wait_len)-len(self.temp) self.temp+=data[:tl] data=data[tl:] elif not self.wait_len and not ''|'' in data:#crap return if self.wait_len and self.wait_len == len(self.temp):#okay, full message self.data_ready.emit(self.temp) self.wait_len , self.temp = '''','''' if not data: return def print_command(self,data): print ''data!'' def get_sstate(self): print self.state() def on_error(self): print ''error'', self.errorString() self.close() self.connectToHost(''dev.ulab.ru'', 10000) def on_disconnect(self): print ''disconnected!'' def on_connected(self): print ''connected!'' self.send(json.dumps( {''command'' : "operator_insite", ''password'' : "376c43878878ac04e05946ec1dd7a55f", ''login'' : "nsandr", ''version'':unicode("1.2.9")})) if __name__ == "__main__": app = QCoreApplication(sys.argv) main_socket = UpQSocket() state_timer = QTimer() state_timer.setInterval(1000) state_timer.timeout.connect(main_socket.get_sstate) state_timer.start() main_socket.connectToHost(''dev.ulab.ru'', 10000) sys.exit(app.exec_())

Aquí está la salida:

connectToHost 1 1 connected! data! data! 3 3 3 3 3 error The remote host closed the connection close! disconnected! connectToHost 2 2


Solución:

import functools def on_error(self): print ''error'', self.errorString() QTimer.singleShot(2000, functools.partial(self.connectToHost, ''localhost'', 9999)) # 2000 - your prefered reconnect timeout in ms

Actualizar

Hay más solución correcta en los comentarios para Qt bugreport QTBUG-18082 . Aquí está la implementación de Python:

@QtCore.pyqtSlot() def do_reconnect(self): print ''Trying to reconnect'' self.connectToHost(''localhost'', 9999) def on_error(self): print ''error'', self.errorString() QtCore.QMetaObject.invokeMethod(self, ''do_reconnect'', QtCore.Qt.QueuedConnection)

o solo:

QTimer.singleShot(0, self.do_reconnect) # or any callable, slot is unnecessary

que de todos modos llamará a QtCore.QMetaObject.invokeMethod con QueuedConnection tipo de conexión ( fuente )