0

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

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

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

尽管如此,客户端没有收到“断管错误”,并且可以继续发送数据。

这怎么可能发生?

这是代码:

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 问题。

4

2 回答 2

1

SLOT函数需要一个表示插槽名称的字符串,并且它应该在插槽的目标之前:

self.connect(self.socket, SIGNAL("connected()"), self, SLOT("connected()"))

但如果没有引号,您将立即调用连接线所在的函数。由于您甚至没有使用QtCore.Slot/装饰器将这些函数声明为插槽,因此如果您使用该函数pyqtSlot,则在发出信号时无论如何都不会调用它们。SLOT

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

self.connect(self.socket, SIGNAL("connected()"), self.connected)

或者

self.socket.connected.connect(self.connected)

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

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

于 2013-07-31T12:33:17.197 回答
1

可能是一个半开的套接字——你不能相信客户端总是正确地打开或终止会话。客户端可能会在没有正确挂断服务器的情况下断开连接?QTcpServer代码我没看过,可能是有人端口扫描你的盒子造成的?

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

于 2013-07-31T11:57:45.893 回答