我在Qt5中编写了一个简单的TCP服务器,其任务可以简化为:
侦听端口上的连接
有人连接后,从中读取一个字符串,然后打印字符串
关闭套接字并侦听下一个连接
服务器的代码是这样的:
class Server:public QObject
{
Q_OBJECT
public:
QTcpServer* TcpServer;
QTcpSocket* TcpSocket;
void Start();
public slots:
void OnConnection();
};
void Server::Start()
{
TcpServer = new QTcpServer();
TcpServer->listen(QHostAddress::Any, 9999);
connect(TcpServer, &QTcpServer::newConnection, this, &Server::OnConnection);
}
void Server::OnConnection()
{
qDebug() << "connected";
TcpSocket = TcpServer->nextPendingConnection();
connect(TcpSocket, &QTcpSocket::readyRead, this, [=]()
{
qDebug() << "received:" << TcpSocket->readAll();
TcpSocket->close();
});
}
然后,我为客户端提供了这段代码:
QTcpSocket socket;
socket.connectToHost(QHostAddress::LocalHost, 9999);
auto x = QString("Some information").toUtf8();
socket.write(x);
socket.close();
如果我只在控制台应用程序中运行它,或者在我的项目中运行它,那么此代码段工作正常:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w; // main window of my application
w.show();
QTcpSocket socket;
socket.connectToHost(QHostAddress::LocalHost, 9999);
auto x = QString("Some information").toUtf8();
socket.write(x);
socket.close();
return a.exec();
}
这是令我困惑的部分:
在主窗口中,有QPushButton
,其clicked
信号连接到一个插槽,在此插槽中我将调用包含代码段的函数。该函数主要处理设置主窗口的布局(我使用QStackedWidget
),并且当执行代码片段时,它的工作方式不同。
从服务器的日志中我认为套接字可以连接到服务器,但是QTcpSocket::readyRead
无法触发,因此服务器总是在等待数据,即使代码段中的所有五行也是如此已执行。(在我提供的代码中,服务器的日志只有“已连接”而没有以下数据。)
我不知道为什么如果我把它放在这个函数中,就无法触发服务器的QTcpSocket::readyRead
。有人可以解释一下吗?
感谢您阅读我的问题: - )
答案 0 :(得分:0)
当您编写控制台应用程序时,可以使用您的代码段进行一些修改,因为您不必处理阻止GUI。只需使用以下方法:
waitForConnected
waitForByttesWritten
但是,如果您编写GUI,请使用信号
首先在致电connectToHost
后,等待connected
信号。然后你可以写你的数据。
之后等待bytesWritten信号,并确保bytes
参数等于write
方法返回的值。当一切正常时,你可以关闭插座。