我想创建一个 SSL 服务器,所以我继承了 QTcpServer 并覆盖了 incomingConnection()
,我在这里创建了一个 QSslSocket
, 设置它的描述符,然后调用 QSslSocket::startServerEncryption
.此时我需要等待 QSslSocket::encrypted()
要发出的信号,只有在那之后我的服务器才会发出 newConnection()
信号。客户端代码会认为它正在使用 QTcpSocket,但实际上会使用安全套接字。
但是QTcpServer 总是发出 newConnection()
打电话后 incomingConnection()
(我查看了 the source of QTcpServer ):
void QTcpServerPrivate::readNotification()
{
// .........
q->incomingConnection(descriptor);
QPointer<QTcpServer> that = q;
emit q->newConnection();
// .........
}
所以我的问题是,有什么方法可以防止 QTcpServer
从发射 newConnection()
,直到我准备好自己发射它?
我想要这个的原因是我希望我的类能够被用作 QTcpServer 的直接替代品,通过不知道它正在使用它的代码,所以它必须完全像 QTcpServer 一样工作:
QTcpServer* getServer(bool ssl)
{
return ssl ? new SslServer : new QTcpServer;
}
我的 SslServer 类代码目前是这样的:
void SslServer::ready()
{
QSslSocket *socket = (QSslSocket *) sender();
addPendingConnection(socket);
emit newConnection();
}
void SslServer::incomingConnection(int socketDescriptor)
{
QSslSocket *serverSocket = new QSslSocket;
if (serverSocket->setSocketDescriptor(socketDescriptor)) {
connect(serverSocket, SIGNAL(encrypted()), this, SLOT(ready()));
serverSocket->startServerEncryption();
} else {
delete serverSocket;
}
}
最佳答案
这里有一个在这种情况下可行的想法:在您的 QTcpServer
子类中重新定义 newConnection
信号。
如果这样做,与服务器实例连接的对象将不会收到 QTcpServer
的信号“版本”,只会收到您直接从子类发出的信号。
这是一个概念证明:A
类是 QTcpServer
,foo
是您试图“劫持”的信号,bar
只是您不需要触摸的 QTcpServer
的另一个(假设的)信号。
class A: public QObject
{
Q_OBJECT
public:
A() {};
virtual void doit() {
qDebug() << "A::doit";
emit foo(1);
emit bar(1);
}
signals:
void foo(int);
void bar(int);
};
Class B
是您的子类。请注意,它重新定义了信号 foo
,但没有对 bar
做任何事情。
class B: public A
{
Q_OBJECT
public:
B() {};
virtual void doit() {
qDebug() << "B::doit";
emit foo(2);
emit bar(2);
}
signals:
void foo(int);
};
C
类是一个潜在的客户端,它连接来自 B
实例的信号/槽,就像连接 A
实例一样。
class C: public QObject
{
Q_OBJECT
public:
C() {
B *b = new B;
connect(b, SIGNAL(foo(int)), this, SLOT(foo(int)));
connect(b, SIGNAL(bar(int)), this, SLOT(bar(int)));
/* 1 */
b->doit();
/* 2 */
b->A::doit(); // call parent class's function
};
public slots:
void foo(int i) {
qDebug() << "foo: " << i;
}
void bar(int i) {
qDebug() << "bar: " << i;
}
};
这是构造 C
的输出:
B::doit // this is /* 1 */
foo: 2
bar: 2
A::doit // this is /* 2 */
bar: 1
... 仅此而已。 A
的 emit foo(1)
没有连接到 C
的 foo
插槽,它永远不会到达C
。 A
的 emit bar(1)
按预期工作,该信号未受影响。
使用该设置,您可以在类准备就绪时发出 newConnection
,QTcpServer
版本的信号将不会被您的用户对象接收。
关于c++ - 子类化 QTcpServer 时,如何延迟发出 newConnection() 信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14143730/