首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在Qtcpsocket的readAll回调中调用readyRead时没有任何内容?

为什么在Qtcpsocket的readAll回调中调用readyRead时没有任何内容?
EN

Stack Overflow用户
提问于 2013-07-31 11:22:57
回答 2查看 760关注 0票数 0

我正在构建一个最小的套接字服务器,当它收到消息时会显示一个窗口。

服务器使用newConnection信号获取客户端连接,并为每个套接字连接合适的信号(已连接、断开和readyRead)。

当运行服务器程序并将一些数据发送到适当的地址时,对于发送的每一个数据,先连接一个QTCPSocket,然后是readyRead,然后立即断开连接。在readyRead回调中,readAll不返回任何内容。(我想这就是断开信号的原因)。

尽管如此,客户端仍然不会得到“坏掉的管道错误”,并且可以继续发送数据。

怎么会发生这种事?

下面是代码:

代码语言:javascript
复制
class Client(QObject):
    def connects(self):
        self.connect(self.socket, SIGNAL("connected()"), SLOT(self.connected()))
        self.connect(self.socket, SIGNAL("disconnected()"), SLOT(self.disconnected()))
        self.connect(self.socket, SIGNAL("readyRead()"), SLOT(self.readyRead()))
        self.socket.error.connect(self.error)
        print "Client Connected from IP %s" % self.socket.peerAddress().toString()

    def error(self):
        print "error somewhere"

    def connected(self):
        print "Client Connected Event"

    def disconnected(self):
        self.readyRead()
        print "Client Disconnected"

    def readyRead(self):
        print "reading"
        msg = self.socket.readAll()
        print QString(msg), len(msg)
        n = Notification(QString(msg))
        n.show()

class Server(QObject):
    def __init__(self, parent=None):
        QObject.__init__(self)
        self.clients = []

    def setup_client_socket(self):
        print "incoming"
        client = Client(self)
        client.socket = self.server.nextPendingConnection()
        #self.client.socket.nextBlockSize = 0
        client.connects()
        self.clients.append(client)

    def StartServer(self):
        self.server = QTcpServer()
        self.server.listen(QHostAddress.LocalHost, 8888)
        print self.server.isListening(), self.server.serverAddress().toString(), self.server.serverPort()
        self.server.newConnection.connect(self.setup_client_socket)

更新: --我直接用python中的socket模块进行了测试,它可以工作。因此,我的机器和网络的总体设置并不是罪魁祸首。这可能是一些QT问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-31 12:33:17

SLOT函数需要一个表示槽名的字符串,它前面应该是插槽的目标:

代码语言:javascript
复制
self.connect(self.socket, SIGNAL("connected()"), self, SLOT("connected()"))

但是没有引号,您将立即调用连接线所在的函数。由于您甚至没有使用QtCore.Slot/pyqtSlot装饰符将这些函数声明为插槽,所以如果使用SLOT函数,在发出信号时也不会调用它们。

对于未修饰的python函数,应该使用以下语法之一:

代码语言:javascript
复制
self.connect(self.socket, SIGNAL("connected()"), self.connected)

代码语言:javascript
复制
self.socket.connected.connect(self.connected)

注意,在最后一个参数的末尾缺少()

此外,您不应该在readyRead中调用disconnected,如果在断开连接之前有数据要读取,则很可能已经调用了readyRead函数。

票数 1
EN

Stack Overflow用户

发布于 2013-07-31 11:57:45

可能是半打开的套接字--您不能信任客户端总是正确地打开或终止会话。客户端可能没有在服务器上执行适当的挂起就断开了连接?我还没有看过QTcpServer代码,但它可能是由某个端口扫描您的框造成的?

无论哪种方式,服务器都应该能够优雅地处理坏的或没有的数据。互联网是一个疯狂的地方,到处都是各种奇怪的数据包。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17968977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档