QTcpSocket:消息不是从另一个线程发送的
QTcpSocket: message not send from another thread
我知道这个主题已经有很多主题了,但没有人能纠正我的问题。。。我希望有人能找到解决办法。
主题:我正在开发一个多线程游戏服务器。然后,我重载TcpServer来写我的等等…
void TcpServerCustomersHandler::incomingConnection(qintptr socketDescriptor)
{
ThreadCustomer* client = new ThreadCustomer(socketDescriptor);
connect(client, &ThreadCustomer::finished, client, &ThreadCustomer::deleteLater);
client->start();
}
我已经编写了另一个重载QThread的类,并编写了我的连接。在"问答"模式下,它是有效的。我收到消息并回复。
void ThreadCustomer::run()
{
qDebug() << "Starting thread: " << m_socketDescriptor;
m_tcpSocket = new QTcpSocket();
if(!m_tcpSocket->setSocketDescriptor(m_socketDescriptor))
{
qCritical() << "Error creation thread:" << m_tcpSocket->errorString();
return;
}
connect(m_tcpSocket, &QTcpSocket::readyRead, this, &ThreadCustomer::onReadyRead_TcpSocket, Qt::DirectConnection);
connect(m_tcpSocket, &QTcpSocket::disconnected, this, &ThreadCustomer::onDisconnected_TcpSocket, Qt::DirectConnection);
connect(InstanceManager::instance(), &InstanceManager::readyRead, this, &ThreadCustomer::onReadyRead_InstanceManager);
exec();
}
void ThreadCustomer::onReadyRead_TcpSocket()
{
QByteArray message = m_tcpSocket->readAll();
//works...
m_tcpSocket->write(message);
}
但由于这是一个游戏服务器,我希望他能够发送"通知"。这意味着在没有收到任何消息的情况下向玩家发送消息。这些通知由单例"InstanceManager"发送。
void ThreadCustomer::onReadyRead_InstanceManager(QByteArray message)
{
m_tcpSocket->write(message);
}
这就是我的问题。当调用"write(("时,不会发出任何消息,我有一条著名的消息:"QSocketNotificationer:套接字通知程序无法从另一个线程启用或禁用"。我知道我有这个消息,因为"write(("是从另一个线程调用的,尽管有连接。
不幸的是,我找不到解决方案。有人有主意吗?
好吧,感谢@wtom,我想出了第一个基于队列的解决方案。
我在QThread中使用QTimer来处理消息并避免冲突。其他:
void ThreadCustomer::run()
{
qDebug() << "Starting thread: " << m_socketDescriptor;
m_tcpSocket = new QTcpSocket();
if(!m_tcpSocket->setSocketDescriptor(m_socketDescriptor))
{
qCritical() << "Error creation thread:" << m_tcpSocket->errorString();
return;
}
m_timerWritting = new QTimer();
connect(m_timerWritting, &QTimer::timeout, this, &ThreadClient::onTimeOut_timerWritting, Qt::DirectConnection);
m_timerWritting->start(500);
connect(m_tcpSocket, &QTcpSocket::readyRead, this, &ThreadClient::onReadyRead_TcpSocket, Qt::DirectConnection);
connect(m_tcpSocket, &QTcpSocket::disconnected, this, &ThreadClient::onDisconnected_TcpSocket, Qt::DirectConnection);
connect(InstanceManager::instance(), &InstanceManager::readyRead, this, &ThreadClient::onReadyRead_InstanceManager, Qt::QueuedConnection);
exec();
}
void ThreadCustomer::onReadyRead_InstanceManager(QByteArray message)
{
m_listMessageToSend.append(message);
}
void ThreadCustomer::onTimeOut_timerWritting()
{
if(m_listMessageToSend.count() > 0)
{
QByteArray message = m_listMessageToSend.takeFirst();
m_tcpSocket->write(message);
}
}
我不知道这是否是更好的解决方案,但它有效:(
我不记得它是如何完成的,所以它更像是伪代码,但关键是当您将InstanceManager::readyRead连接到ThreadCustomer::onReadyRead_InstanceManager时(在ready read事件上写入-是预期的吗,执行void TcpServerCustomersHandler::incomingConnection(qintptr socketDescriptor(的。这不是你想要的。您必须将ThreadCustomer的线程关联更改为执行ThreadCustomer::run((的线程
编辑ThreadCustomer是从QThread派生而来的,对吗?
void TcpServerCustomersHandler::incomingConnection(qintptr socketDescriptor)
{
ThreadCustomer* client = new ThreadCustomer(socketDescriptor);
client->moveToThread(&client); // in canonical way QThread and ThreadCustomer are different objects: client->moveToThread(&thread);, but may be it will work like this?
connect(client, &ThreadCustomer::finished, client, &ThreadCustomer::deleteLater);
client->start();
}
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 从C++11中的线程返回一个值
- qt多线程:计算一个积分
- volatile变量在一个客户线程和一个生产者线程中是否安全
- C++ pthread,两个线程读取一个全局变量
- 如何启动一个 boost::线程运行一个成员函数
- 如果另一个线程将一个元素推到向量的末尾,则向量上的迭代器无效
- Qt::线程是一个库还是仅仅是一个类
- 当一个线程锁定一个大映射时,如何避免冻结其他线程
- C++-如何让多个线程写入一个文件
- 为什么我的线程被一个关键部分阻塞,而没有被任何东西抓住
- 一个线程读一个线程写,std::deque是安全的
- 从c++线程发出一个信号
- 通信b/w两个线程在一个公共的数据结构.设计问题
- 如何使用boost运行线程另一个对象函数与回调
- 我可以在OpenMP分配多个线程到一个代码段
- 当我从线程B读取相同的变量时,我能从线程a写入一个变量吗
- 线程中一个套接字发送/接收
- 跨线程发送一个glib信号
- 用一个插入线程和一个读线程映射并发性