- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在下面提供了我的全部代码。请原谅我的设计,因为我是 Qt 的新手,这是一个快速而肮脏的例子。
我想做的是创建一个管理 QTcpServer 监听器的 QThread。我希望它能够在停止时关闭监听器,然后在再次启动时重新打开它。请忽略监听器现在可能被泄露的事实,我稍后会解决这个问题。
我认为问题在于,当调用 Stop 时,它会在与创建它的线程(它是在 TcpServerThread 上创建的)不同的线程(从主线程调用)上调用 m_listener->close() 方法。所以问题是,我该如何解决?或者我如何重新设计它以避免这个问题?
这不是完整的设计,我做了一个模仿真实事物的玩具示例。
tcpserverthread.h
#ifndef TCPSERVERTHREAD_H
#define TCPSERVERTHREAD_H
#include <QObject>
#include <QThread>
class QTcpServer;
class TcpServerThread : public QThread
{
Q_OBJECT
public:
TcpServerThread();
void run();
void Start();
void Stop();
public slots:
void newConnection();
private:
QTcpServer* m_pListener;
};
#endif // TCPSERVERTHREAD_H
tcpserver线程.cpp
#include "tcpserverthread.h"
#include "tcpserver.h"
#include <iostream>
#include <QTcpServer>
#include <QTcpSocket>
#include <QCoreApplication>
TcpServerThread::TcpServerThread()
{
}
void TcpServerThread::run()
{
std::cout << "thread started ..." << std::endl;
std::cout << "listener starting ..." << std::endl;
m_pListener = new QTcpServer();
connect(m_pListener, SIGNAL(newConnection()), this, SLOT(newConnection()));
if(!m_pListener->listen(QHostAddress::Any, 1234))
{
std::cout << "listener could NOT START - " << m_pListener->errorString().toStdString() << std::endl;
}
else
{
std::cout << "listener SUCCESSFULLY STARTED" << std::endl;
}
// std::cout << "thread running..." << std::endl;
// m_pListener = new TcpServer();
// m_pListener->Start();
exec();
}
void TcpServerThread::newConnection()
{
qDebug() << "in new conn ... ";
//std::cout << "in new conn.." << std::endl;
QTcpSocket *soc = m_pListener->nextPendingConnection();
soc->write("hello client");
}
void TcpServerThread::Start()
{
start();
}
void TcpServerThread::Stop()
{
std::cout << "TcpServer Stopping . . . " << std::endl;
//this close is the line that causes the problem...
m_pListener->close();
this->quit();
}
主要.cpp
#include <QCoreApplication>
#include <iostream>
#include <QTcpServer>
#include "tcpserver.h"
#include "tcpserverthread.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
TcpServerThread *t = new TcpServerThread();
t->Start();
t->Stop();
return a.exec();
}
如果您在 main 中注释掉对 t->Stop 的调用,您可以运行它并使用 telnet(或 putty)连接到它 @ 127.0.0.1:1234。
我想让它停止,然后再次启动,连接将正常工作。
最佳答案
好的,所以您在这里以错误的方式使用 QThread。如果您要从 QThread 继承,那么这应该是因为您想扩展线程的功能,这不是您想要的。
QThread 是一个用于控制线程的类,对您来说,不应该是您的类的一部分。相反,您应该设计您的类 TcpServer
(而不是 TcpServerThread
),但删除线程元素。然后制作 run()、start() 和 stop() 槽。您还需要从 QObject 继承才能使用信号和插槽。像这样:
class TcpServer: public QObject
{
Q_OBJECT // don't forget this
:
:
}
然后在 main 中你可以创建你的线程和你的类,然后将你的类移动到线程中:
TcpServer *pTcpServer = new TcpServer();
QThread *pThread = new QThread;
pTcpServer->moveToThread(pThread);
// Connect thread start to your run() function
connect(pThread, &QThread::started, pTcpServer, &TcpServer::run, Qt::QueuedConnection);
// Now run your thread, when it starts your run() slot will be called
thread->start();
至于调用您的开始/停止 - 是什么触发了开始/停止?我假设其他一些对象将启动/停止服务器或某些事件?在任何情况下,您都将以相同的方式连接它们:
connect(pSomeClass, &SomeClass::startTcpServer, pTcpServer, &TcpServer::start, Qt::QueuedConnection);
connect(pSomeClass, &SomeClass::stopTcpServer, pTcpServer, &TcpServer::stop, Qt::QueuedConnection);
注意
我认为您看到在主线程中创建一些对象的原因是因为您直接在类中调用函数(start()
/stop()
)。跨线程“边界”执行此操作并不安全,因为采取的任何操作(或分配的对象)都将在调用线程(主线程)内完成。您需要使用槽/信号机制(或其他一些线程安全机制)。
关于c++ - 如何在 QThread 上创建 QTcpServer 然后从主线程中停止它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37871892/
我对 QTcpServer 如何在线程和阻塞方面的幕后工作感兴趣。 QTcpServer有一个 listen()立即返回的方法。如果监听成功开始,服务器将发出信号 newConnection() .我
我在 QT 框架 (c++) 中有一个软件,它可以将处理过的(本地)数据发送到其他服务器并接收在其他服务器上处理过的相同(外部)数据并进行比较。 当处理大量本地数据时会出现问题,外部数据会被缓冲并且在
当我尝试使用QTcpServer 监听任何端口,并在调试器 下运行应用程序时,我总是会收到“未知错误”。当我在没有调试器的情况下运行这个程序时——一切似乎都很好。 #include #include
我使用 QTcpServer来自带有 C++ 的 Qt 框架。 我开始了 ret = tcpServer->listen(QHostAddress::Any, 9871) 与 QHostAddress
我正在 Windows 7 上的 Qt 4.7 中开发一个 RPC 服务器。为了同时参与多个执行,每个请求都在一个单独的线程中运行(因为函数可能会阻塞)。我继承自 QTcpServer 并重新实现了
我正在编写客户端-服务器应用程序,它使用 QTcpSocket 和 QTcpServer。这是断开连接的()插槽: 服务器: void testServer::disconnected() {
我正在尝试使用 QT 在 C++ 中创建一个 TCP 服务器。我有代码,但是当我尝试使用 SocketTest 连接到服务器时,它说连接被拒绝(很可能是由于服务器未运行)。 这是在我的 tcplist
我正在为服务器编程,我为服务和管理器编程。当我使用 UI 服务器管理器停止服务器时,服务器调用一个名为“stopServer()”的函数,该函数包含以下内容: qDebug() getSocket()
我正在 Qt 中编写 TCP 服务器,它将提供大文件。应用逻辑如下: 我继承了 QTcpServer 并重新实现了 incomingConnection(int) 在 incomingConnecti
我的VS2010只能#include 但不能 #include . Qt助手建议被包含以应用 TCP 服务器,但我的 VS2010 似乎找不到此 header ,但它可以找到 这两个 header
我正在尝试一个非常非常简单的 QT 网络程序。由于某种原因,它在没有任何错误消息的情况下执行时崩溃,因为它没有按预期将任何输出打印到命令行。这是代码: qtTCPservertest.pro QT
我刚刚写了一个简单的qtcpserver,几乎就是这个例子:QT QTcpServer::incomingConnection(qintptr handle) not firing? 服务器基本上是工
我有一个这样的线程子类 class MyThread : public QThread { public: MyThread (void); ~MyThread (void);
我正在尝试使用 QTcpServer 和 Qt 5.3.1 在 Android 上启动服务器,但服务器没有启动,我得到“不支持的套接字操作”。它在 Windows 上运行良好。 代码如下: void
我正在做一个简单的服务器-客户端应用程序。但是,客户端从服务器端获得了一些未定义的行为。找回错误码后,才知道是服务器断开了连接。 这是服务端main.cpp #include #include #
我正在尝试将 char 数据从 PHP 脚本传送到 QTcpServer 并且服务器收到连接并且也可以回复,但我无法获取 php 发送的数据。 我做错了什么? PHP 脚本: #include "f
我正在制作一个简单的程序,它将“连接”到自身然后发送数据。它启动一个 QTcpServer 然后等待任何传入的连接。我有一个单独的函数,它将依次尝试在我决定的本地主机和端口上连接到该服务器。这在我在命
我只想用特定地址设置我的 QTcpServer。我已经用这段代码试过了,但它不起作用...... server.listen(QHostAddress::setAddress("127.0.0.1
我想将数据从特定位置(共享内存)传递到客户端应用程序。一个线程不断地轮询 SHM 以获取新数据,一旦它得到一些东西,它就会将它传递给客户端。 可以有多个此类客户端应用程序实例将连接到我的 (QTcpS
我用 winsock2.h 找到了这个套接字代码 http://www.tidytutorials.com/2009/12/c-winsock-example-using-client-server.
我是一名优秀的程序员,十分优秀!