我知道我无法在线程之间与 QTcpSocket 通信,但我找不到我做错了什么。
一旦我向另一个线程中的 QTcpSocket 发送数据发射信号,QSocketNotifier 应该禁用自身以让 QTcpSocket 读取数据。因为我遇到了上面的错误,所以它不会被禁用并且不会发出 readyRead() 信号。
我使用 QEventLoop 来实现阻塞机制(同步通信 - ModBus 协议)而不锁定主循环。我不能使用 waitReadyRead() 因为我过去在使用该函数时遇到了问题(超时):
https://bugreports.qt-project.org/browse/QTBUG-24451
和
https://bugreports.qt-project.org/browse/QTBUG-14975
有人可能会好奇为什么我要设置这么多线程:
Thread1:每次新的通信都会创建一个新线程,并用“全局”互斥锁将其锁定,以确保没有其他函数会执行并行通信。在该线程内 - 在准备和锁定互斥锁之后,我通过 Thread2 中的 Qt::QueuedConnection 信号(与设备的持续通信)与 QTcpSocket 通信。
Thread2:QTcpSocket 对象创建并移动到线程。一旦我连接到设备,我就不想关闭套接字。因为我阻塞了主事件循环,所以我需要其他事件循环来运行来自 QTcpSocket 的信号。
和代码:
void someFunctionThatWantToSendData( void ) // Main Thread
{
ElfKernel::KernelSingleton::Instance().getGUIcontrol()->getCtrlUnitPtr()->execModbusCommand( someParameters, someCommunicationFunction );
}
ElfKernel::FrameReceived ControlUnit::execModbusCommand( std::list<unsigned int> paramsToCommand, FunctionStringList execCommand ) // Main Thread
{
ModbusCommandReply* mcr = new ModbusCommandReply(); // THREAD_1!!!!!! this object run in a Thread -> ModbusCommandReply : public QThread …Run Code Online (Sandbox Code Playgroud) 我创建简单的多线程服务器:
server.h
class Server : public QTcpServer
{
Q_OBJECT
public:
explicit Server(QObject *parent = 0);
void StartServer();
protected:
void incomingConnection(int handle);
private:
QThreadPool *pool;
};
Run Code Online (Sandbox Code Playgroud)
server.cpp:
#include "server.h"
Server::Server(QObject *parent) :
QTcpServer(parent)
{
pool = new QThreadPool(this);
pool->setMaxThreadCount(10);
}
void Server::StartServer()
{
this->listen(QHostAddress(dts.ipAddress),80));
}
void Server::incomingConnection(int handle)
{
Runnable *task = new Runnable();
task->setAutoDelete(true);
task->SocketDescriptor = handle;
pool->start(task);
}
Run Code Online (Sandbox Code Playgroud)
runnable.h
class Runnable : public QRunnable
{
public:
Runnable();
int SocketDescriptor;
protected:
void run(); …Run Code Online (Sandbox Code Playgroud) 我在QT尝试多线程服务器.但是,我不断收到这个恼人的错误:
错误:不是信号或插槽声明(第21行)
这是我的代码:
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QTcpSocket>
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(int ID, QObject *parent = 0);
void run();
signals:
void error(QTcpSocket::SocketError socketerror);
public slots:
void readyRead();
void disconnected();
public slots:
QTcpSocket *socket;
int socketDescriptor; //Socket ID Number
};
#endif // MYTHREAD_H
Run Code Online (Sandbox Code Playgroud) 是否可以监听 QTcpSocket?我在 Tcp 上有一个简单的 p2p 连接。但是我找不到在随机空闲端口上启动 QTcpSocket 的方法。我应该使用 QTcpServer 吗,还是只有 1 个连接有点矫枉过正?
使用 Qt 编写聊天。有问题。我客户端的 QTcpSocket 保持连接状态,但服务器发出 newConnection() 信号。不需要网络会话。这是为什么?这是一些代码:
ChatClient::ChatClient(QObject *parent)
: QObject(parent) {
tcpSocket = new QTcpSocket(this);
QNetworkConfigurationManager manager;
if (QNetworkConfigurationManager::NetworkSessionRequired
& manager.capabilities()) {
qDebug() << "Network session required";
}
connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(error(QAbstractSocket::SocketError)));
connect(tcpSocket, SIGNAL(connected()),
this, SLOT(requestForID()));
connect(tcpSocket, SIGNAL(readyRead()),
this, SLOT(receiveMessage()));
tcpSocket->connectToHost("192.168.0.100", PORT);
}
void ChatClient::requestForID() {
qDebug() << "Connected, requesting for ID";
QByteArray segment;
QDataStream out(&segment, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_7);
out << (quint16)0 << ID;
out.device()->seek(0);
out << (quint16)(segment.size() - sizeof(quint16));
tcpSocket->write(segment);
}
Run Code Online (Sandbox Code Playgroud)
requestForID() 永远不会被执行
ChatServer::ChatServer(QObject *parent)
: QObject(parent) {
tcpServer …Run Code Online (Sandbox Code Playgroud) 我正在设计一个使用Qt创建者访问远程桌面的应用程序.为了从远程桌面获取"退出"信号(在完成我的目的之后),我使用的是Tcpserver和Tcpsocket.我的Pc充当服务器,而远程PC充当客户端.我使用以下概念:
Server pc 1.按PushButton访问远程屏幕(使用tightvnc以全屏模式).2.启动服务器并侦听任何活动连接(我正在使用端口9876).3.找到活动连接.连接到客户端.4.关闭远程访问.5.切换回本地屏幕.6.服务器关闭
客户端PC 1.按退出按钮关闭远程访问.2.按下退出按钮时3.连接到主机.4.将"退出"发送到服务器5.断开与主机的连接6.关闭连接.
几次尝试都可以正常工作(比方说10次)
但在它开始给出错误"连接拒绝错误"之后.而且我无法从远程访问中恢复,直到重新启动我的远程PC.
我尝试过使用Reset但结果是一样的.
任何人都有任何想法???
这是我的客户端代码
#include "ctrlboardclient.h"
#include <QHostAddress>
#include <QObject>
#include <QtGui/QApplication>
#include <QDebug>
bool CtrlBoardClient::status_flag = false; /* Flag to check the transfer status of Data */
CtrlBoardClient::CtrlBoardClient()
{
connect(&client, SIGNAL(connected()), this, SLOT(startTransfer()));
connect(&client, SIGNAL(readyRead()), this, SLOT(recieve_msg()));
connect(&client, SIGNAL(disconnected()), this, SLOT(disconnectstatus()));
connect(&client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(getErrorCode(QAbstractSocket::SocketError)));
}
bool CtrlBoardClient::start(QString address, quint16 port)
{
QHostAddress addr(address);
bool rval = client.reset();
qDebug() << "Reset before Connect to Host = " << rval;
client.connectToHost(address, port);
if …Run Code Online (Sandbox Code Playgroud) 我收到转账时遇到问题.
当我发送它时,QTcpSocket-> readAll()没有读取足够的字节.当我发送像15k字节时,它只读取它的一部分,然后什么都不做.我做错了什么?
QByteArray array;
array = socket->readAll(); //just reads some part, not fully.
Run Code Online (Sandbox Code Playgroud)
为什么?
对不起我的英语不好.
问候.
目前在我的QT代码中我有这样的事情:
QByteArray tick_stream;
clntSocket->waitForReadyRead();
tick_stream = clntSocket->read(800);
Run Code Online (Sandbox Code Playgroud)
在它所述的文件中
此功能将阻塞,直到有新数据可供读取并且已发出readyRead()信号.该函数将在msecs毫秒后超时; 默认超时为30000毫秒
有什么方法可以让waitForReadyRead在我的阻止应用程序中等到无限
我正在创建一个简单的(ish)telnet服务器,现在正在使用valgrind进行调试.代码运行得很好,但valgrind抱怨程序终止时内存丢失...而罪魁祸首是我创建一个新QTcpSocket的行:
void TelnetConnection::run()
{
tcpSocketPtr = new QTcpSocket(); // ** remove this due to parent error
if (!tcpSocketPtr->setSocketDescriptor(socketDescriptor)) {
emit error(tcpSocketPtr->error());
return;
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试将'this'传递给QTcpSocket()但是我尝试连接的信号槽抱怨与另一个父关联.这是问题吗?线索?而且......答案是什么?
我通过将tcpsocketptr赋值为0来删除/释放tcpsocketptr,如下所示.是对的吗?
void TelnetConnection::clientDisconnected()
{
tcpSocketPtr = 0; // ** Cure memory loss?
TelnetConnection::s_clientCount--;
Logger *log = Logger::instance();
log->record(Logger::Information,EVENTID_TELNET_DISCONNECTION,"Telnet client "+QString::number(m_clientNumber) +": Disconnecting");
QThread::quit(); // Exit ths event loop for this thread
}
Run Code Online (Sandbox Code Playgroud) 使用时如何使用Qtcpsocket发送字符串
tcpsocket->write("hello");
tcpsocket->write("world");
etc..
tcpSocket->flush();
tcpSocket->waitForBytesWritten(3000);
Run Code Online (Sandbox Code Playgroud)
它以一个字符串“hello world”发送它,我想让它一次只写一个,我想让客户端接收“hello”然后是“world”。
qt ×10
qtcpsocket ×10
c++ ×6
qtcpserver ×2
connect ×1
disconnected ×1
linux ×1
memory-leaks ×1
networking ×1
qthread ×1
sockets ×1