我在使用 QTcpSocket 时遇到了一个奇怪的问题,我在网上搜索过,但找不到其他有同样问题的人。
我有两个基本应用程序,一个客户端和一个服务器,如果我在本地机器上运行它们,客户端成功地与服务器建立所有 50 个连接。
如果我在连接到网络的另一台计算机上运行服务器(比如说:10.1.1.1),它每次都会再次连接而不会出现问题。
现在,如果我更改服务器的 main.cpp 以在不同端口(8001 到 8050)下初始化多个服务器,并更改客户端以与每个服务器建立一个连接。两者都在本地运行,它仍然可以正常工作。
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 台机器都连接良好,第二台机器的下 5 台机器在挂起之前也是如此,直到最终连接到最后 10 台机器。
这是在 Qt 版本 4.7.2 上。我在 Fedora 17、Windows 7 上遇到过这个问题,但在Scientific Linux 6 上没有。
客户端/服务器的代码包含在下面,我删除了所有包含以节省一些垂直空间:
客户
客户端.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;
};
客户端.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);
}
主文件
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();
}
服务器
服务器.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();
}
主文件
int main(int argc, char** argv) {
QCoreApplication app(argc, argv);
Server server;
return app.exec();
}