Pyqt; QTcpSocket is always in connectionState after server restart;

I have a subclass of QTcpSocket. And the problem is that when I connect to the server - everything is fine, but after connecting the socket, restart the server (python socketServer, just close and run the script again). Disconnecting the connector and trying to connect while the server is running, but when I start the server again nothing happened, socket.state () is always in ConnectionState .. what's wrong?

Here is a sample code:

# -*- 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_()) 

It displays here:

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

Workaround:

 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 

Update

In the comments for Qt, bugreport QTBUG-18082 has a more correct solution. Here is a Python implementation:

 @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) 

or simply:

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

which in any case will call QtCore.QMetaObject.invokeMethod with connection type QueuedConnection ( source )

+3
source

Source: https://habr.com/ru/post/1395406/


All Articles