如何以几秒的间隔多次使用 QTcpSocket 实例?

2021-12-28 00:00:00 qt tcp c++ qtcpsocket

我必须用 QTcpSocket 多次重复相同的请求,间隔几秒钟.简单的任务,但我不能让它只处理一个对象实例.如何使用相同的 QTcpSocket 实例再次连接到服务器?我已经尝试了许多不同组合的 reset()、resume()、flush()、open(),但它什么也没做.我第二次无法 connectToHost()...

I have to repeat the same request with QTcpSocket multiple times with a couple seconds intervals. Easy task but I can't get it to work with only one instance of object. How to connect to server again using the same instance of QTcpSocket? I've tried reset(), resume(), flush(), open() in many diffrent combinations and it has done nothing. I'm unable to connectToHost() for second time...

推荐答案

你要做的就是connectToHost(),使用连接,然后disconnectFromHost().而已.不多不少.

All you have to do is to connectToHost(), use the connection, then disconnectFromHost(). That's it. Nothing more, nothing less.

下面的例子说明了客户端和服务器套接字实例的重用.服务器实例保存在一个仅在必要时增长的池中.它是为 Qt 5 编写的,使用 C++11.

The below example illustrates the reuse of both client and server socket instances. The server instances are kept in a pool that only grows when necessary. It's written for Qt 5 and uses C++11.

// https://github.com/KubaO/stackoverflown/tree/master/questions/multisocket-22726075
#include <QtNetwork>

class EchoServer : public QTcpServer
{
   QStack<QTcpSocket*> m_pool;
   void incomingConnection(qintptr descr) Q_DECL_OVERRIDE {
      if (m_pool.isEmpty()) {
         auto s = new QTcpSocket(this);
         QObject::connect(s, &QTcpSocket::readyRead, s, [s]{
            s->write(s->readAll());
         });
         QObject::connect(s, &QTcpSocket::disconnected, this, [this, s]{
            m_pool.push(s);
         });
         m_pool.push(s);
      }
      m_pool.pop()->setSocketDescriptor(descr, QTcpSocket::ConnectedState);
   }
public:
   ~EchoServer() { qDebug() << "pool size:" << m_pool.size(); }
};

void setupEchoClient(QTcpSocket & sock)
{
   static const char kByteCount[] = "byteCount";
   QObject::connect(&sock, &QTcpSocket::connected, [&sock]{
      auto byteCount = 64 + qrand() % 65536;
      sock.setProperty(kByteCount, byteCount);
      sock.write(QByteArray(byteCount, 'x2A'));
   });
   QObject::connect(&sock, &QTcpSocket::readyRead, [&sock]{
      auto byteCount = sock.property(kByteCount).toInt();
      if (byteCount) {
         auto read = sock.read(sock.bytesAvailable()).size();
         byteCount -= read;
      }
      if (byteCount <= 0) sock.disconnectFromHost();
      sock.setProperty(kByteCount, byteCount);
   });
}

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   QHostAddress addr("127.0.0.1");
   quint16 port = 5050;

   EchoServer server;
   if (! server.listen(addr, port)) qFatal("can't listen");

   QTcpSocket clientSocket;
   setupEchoClient(clientSocket);

   auto connectsLeft = 20;
   auto connector = [&clientSocket, &addr, port, &connectsLeft]{
      if (connectsLeft--) {
         qDebug() << "connecting" << connectsLeft;
         clientSocket.connectToHost(addr, port);
      } else
         qApp->quit();
   };
   // reconnect upon disconnection
   QObject::connect(&clientSocket, &QTcpSocket::disconnected, connector);
   // initiate first connection
   connector();

   return a.exec();
}

相关文章