派克特(Pyqt);服务器重新启动后,QTcpSocket始终处于connectingState; [英] Pyqt ; QTcpSocket always in connectingState after server restart;

查看:506
本文介绍了派克特(Pyqt);服务器重新启动后,QTcpSocket始终处于connectingState;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个QTcpSocket的子类.问题是:当我花费时间连接服务器时,一切正常,但是套接字连接后,我重新启动了服务器(python socketServer,只需关闭并再次启动脚本),套接字断开连接,并在服务器关闭时尝试重新连接,但是当我再次启动服务器时-什么也没发生,socket.state()始终处于ConnectingState ..怎么了?

I've got a subclass of QTcpSocket. And problem is : when i firt time connect to server - everything ok, but after socket connected i restart server (python socketServer,just close and start script again) socket disconnecting and tryin to reconnect while server is down, but when i start server again - nothing happened, socket.state() always in ConnectingState.. what is wrong ?

以下示例代码:

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

此处输出:

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

推荐答案

解决方法:

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

更新

Qt bugreport

There is more correct solution in comments for Qt bugreport QTBUG-18082. Here is 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)

或者只是:

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

无论如何将使用QueuedConnection锥连接类型调用QtCore.QMetaObject.invokeMethod(

which anyway will call QtCore.QMetaObject.invokeMethod with QueuedConnection conection type (source)

这篇关于派克特(Pyqt);服务器重新启动后,QTcpSocket始终处于connectingState;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆