0

QTcpSocket を使用して奇妙な問題が発生しました。Web を検索しましたが、同じ問題を抱えている人は他に見つかりません。

1 つのクライアントと 1 つのサーバーの 2 つのベアボーン アプリケーションがあります。ローカル マシンで両方を実行すると、クライアントはサーバーへの 50 接続すべてを正常に確立します。

ネットワークに接続された別のコンピューター (たとえば、10.1.1.1) でサーバーを実行すると、毎回問題なく接続されます。

ここで、サーバーの main.cpp を変更して複数のサーバーを異なるポート (8001 から 8050) で初期化し、クライアントを変更して各サーバーに 1 つの接続を確立するとします。両方ともローカルで実行しても問題なく動作します。

int main(int argc, char** argv) {
  QCoreApplication app(argc, argv);

  for (int i = 8001; i <= 8050; ++i) {
    Server server(i);
    return app.exec();
  }
}

しかし、サーバーを 10.1.1.1 に置いて再試行すると、最初の 20 に問題なく接続しますが、次の 20 に接続する前にしばらく (5 秒以上) ハングします。すべてがつながるまで。

最終テストとして、サーバーのインスタンスを別のマシン (10.1.1.2) に置き、各マシンにサーバーの 15 個のインスタンスを作成し、両方に接続しようとしましたが、同じ問題が発生しました。最初のマシンの 15 台すべてが正常に接続し、最終的に最後の 10 台に接続するまでハングする前に、2 台目のマシンの次の 5 台も接続されました。

これは Qt バージョン 4.7.2 にあります。そして、Fedora 17、Windows 7 でこの問題を経験しましたが、 Scientific Linux 6では経験しませんでした。

クライアント/サーバーのコードは以下に含まれています。縦方向のスペースを節約するために、すべてのインクルードを削除しました。

クライアント

client.h

class Client: public QObject {
  Q_OBJECT

public:
  Client(QObject* parent = 0);
  ~Client();
  void start(QString address, quint16 port);

public slots:
  void startTransfer();
  void disconnect() { qDebug("disconnect"); }

private:
  QTcpSocket client;
};

client.cpp

Client::Client(QObject* parent): QObject(parent) {
  connect(&client, SIGNAL(connected()), this, SLOT(startTransfer()));
  connect(&client, SIGNAL(disconnected()), this, SLOT(disconnect()));
}

Client::~Client() {
  client.close();
}

void Client::start(QString address, quint16 port) {
  QHostAddress addr(address);
  qDebug(QString("connecting to %1:%2").arg(address, QString::number(port)).toLocal8Bit().constData());

  client.connectToHost(addr, port);
}

void Client::startTransfer() { 
  qDebug("connected");
  client.write("Hello, world", 13);
}

main.cpp

int main(int argc, char** argv) {
  QCoreApplication app(argc, argv);

  for (int i = 0; i < 50; i++) {
    Client *client = new Client;
    client->start("192.168.0.1", 8888);
  }

  return app.exec();
}

サーバ

server.h

class Server: public QObject {
  Q_OBJECT

public:
  Server(int port = 8888, QObject * parent = 0);
  ~Server();

public slots:
  void acceptConnection();
  void startRead();

private:
  QTcpServer server;
  QList<QTcpSocket *> clients;
};

サーバー.cpp

Server::Server(int port, QObject* parent): QObject(parent) {
  qDebug(qPrintable("new server instance on port " + QString::number(port)));

  connect(&server, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
  server.listen(QHostAddress::Any, port);
}

Server::~Server() {
  server.close();
}

void Server::acceptConnection() {
  QTcpSocket *client = server.nextPendingConnection();
  clients.append(client);

  connect(client, SIGNAL(readyRead()), this, SLOT(startRead()));
}

void Server::startRead() {
  QTcpSocket *client = dynamic_cast<QTcpSocket *>(sender());

  char buffer[1024] = {0};
  client->read(buffer, client->bytesAvailable());
  QString response = QString("%2 on server %3").arg(buffer, QString::number(server.serverPort()));
  std::cout << qPrintable(response) << std::endl;
  client->close();
}

main.cpp

int main(int argc, char** argv) {
  QCoreApplication app(argc, argv);

  Server server;
  return app.exec();
}
4

0 に答える 0