我到处寻找例子,我似乎无法找到解决方案。
所以:我有这个名为DataReceiver的接收类。基本上,我只想从localhost(127.0.0.1)网络上的TCP套接字接收数据。看来我可以写这个socket(我用Wireshark软件检查过),但看起来程序没有收到任何东西。
我在onDataReceived QT SLOT中放置了一个qDebug()语句。此插槽似乎不会在任何时刻触发。我尝试手动编辑mTcpSocket-> readyRead()QT SIGNAL,并且正确调用了插槽,这意味着没有发出信号,因为QTcpSocket没有收到任何信息(或者至少我这样)。
我的电脑是Mac w / macOS High Sierra。我扫描了开放端口,发现51470& 50911是开放的。这些是我测试过的端口。
此课程的代码如下:
class DataReceiver : QObject
{
Q_OBJECT
public:
// Con/Destructors
explicit DataReceiver(QObject *parent = nullptr);
explicit DataReceiver(const QString &pSourceAddress,
const unsigned int &pSourcePort,
QObject *parent = nullptr);
~DataReceiver();
// Network Management
bool connectToHost(void);
// Getters
QVector<float> *getData(void) const;
QTcpSocket *getTcpSocket(void) const;
QString getSourceAddress(void) const;
unsigned int getSourcePort(void) const;
// Setters
void setData(const QVector<float> *pData);
void setSourceAddress(const QString &pSourceAddress);
void setSourcePort(const unsigned int &pSourcePort);
signals:
public slots:
void onConnect();
void onDisconnect();
void onBytesWritten(qint64 bytes);
void onDataReceived();
private slots:
private:
void decodeData(const QByteArray &pMessage);
QTcpSocket *mTcpSocket;
QString mSourceAddress;
unsigned int mSourcePort;
const unsigned int mDataSize = 30;
QVector<float> *mData;
};
// Con/Destructors
DataReceiver::DataReceiver(QObject *parent) :
QObject(parent),
mTcpSocket(new QTcpSocket(this)),
mSourceAddress("127.0.0.1"),
mSourcePort(51470),
mData(new QVector<float>)
{
for( unsigned int i = 0; i < mDataSize; i++)
mData->append(.0);
}
DataReceiver::DataReceiver(const QString &pSourceAddress,
const unsigned int &pSourcePort,
QObject *parent) :
QObject(parent),
mTcpSocket(new QTcpSocket(this)),
mSourceAddress(pSourceAddress),
mSourcePort(pSourcePort),
mData(new QVector<float>)
{
for( unsigned int i = 0; i < mDataSize; i++)
mData->append(.0);
}
DataReceiver::~DataReceiver(){
mTcpSocket->disconnectFromHost();
mTcpSocket->waitForDisconnected();
delete mTcpSocket;
delete mData;
}
// Network Management
bool DataReceiver::connectToHost(void){
connect(mTcpSocket, SIGNAL(connected()), this, SLOT(onConnect()));
connect(mTcpSocket, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
connect(mTcpSocket, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)));
connect(mTcpSocket, SIGNAL(readyRead()), this, SLOT(onDataReceived()));
qDebug() << "connecting...";
//emit mTcpSocket->readyRead(); // For testing. We correctly trigger the onDataReceived slot
mTcpSocket->open(QAbstractSocket::ReadWrite);
mTcpSocket->connectToHost(getSourceAddress(), getSourcePort());
if(!mTcpSocket->waitForConnected(1000))
{
qDebug() << "Error: " << mTcpSocket->errorString();
return false;
}
mTcpSocket->write("Hello ?"); // Test
return true;
}
// Getters
QVector<float> *DataReceiver::getData(void) const{
return mData;
}
QTcpSocket *DataReceiver::getTcpSocket(void) const{
return mTcpSocket;
}
QString DataReceiver::getSourceAddress(void) const{
return mSourceAddress;
}
unsigned int DataReceiver::getSourcePort(void) const{
return mSourcePort;
}
// Setters
void DataReceiver::setData(const QVector<float> *pData){
// Not yet implemented
Q_UNUSED(pData);
}
void DataReceiver::setSourceAddress(const QString &pSourceAddress){
mSourceAddress = pSourceAddress;
}
void DataReceiver::setSourcePort(const unsigned int &pSourcePort){
mSourcePort = pSourcePort;
}
// Public Slots
void DataReceiver::onConnect(){
qDebug() << "connected...";
}
void DataReceiver::onDisconnect(){
qDebug() << "disconnected...";
}
void DataReceiver::onBytesWritten(qint64 bytes){
qDebug() << bytes << " bytes written...";
}
// Private Slots
void DataReceiver::onDataReceived(){
// Not yet implemented, code is for testing
qDebug() << "onDataReceived called !";
while(mTcpSocket->bytesAvailable()){
qInfo() << mTcpSocket->read(mTcpSocket->bytesAvailable());
qDebug() << mTcpSocket->readAll();
}
}
// Private Methods
void DataReceiver::decodeData(const QByteArray &pMessage){
// Not yet implemented
Q_UNUSED(pMessage);
}
mData / mDataSize在此处供将来使用,因此在此处将被忽略。
要发送数据,我尝试使用 netcat :
cat testfile.txt | nc 127.0.0.1 51470
我还创建了一个 DataSender 类,其结构与DataReceiver类相同。 根据Wireshark的说法,这两种方法似乎都是通过TCP写入数据。
class DataSender : QObject
{
Q_OBJECT
public:
// Con/Destructors
explicit DataSender(QObject *parent = nullptr);
~DataSender();
// Network Management
bool connectToHost(void);
void sendData(void) const;
// Getters
QString getDestinationAddress(void) const;
unsigned int getDestinationPort(void) const;
// Setters
void setDestinationAddress(const QString &pDestinationAddress);
void setDestinationPort(const unsigned int &pDestinationPort);
signals:
public slots:
void onConnect();
void onDisconnect();
void onBytesWritten(qint64 bytes);
void onDataReceived();
private:
QTcpSocket *mTcpSocket;
QString mDestinationAddress;
unsigned int mDestinationPort;
};
DataSender::DataSender(QObject *parent) :
QObject(parent),
mTcpSocket(new QTcpSocket(this)),
mDestinationAddress("127.0.0.1"),
mDestinationPort(50911)
{
}
DataSender::~DataSender(){
mTcpSocket->disconnectFromHost();
mTcpSocket->waitForDisconnected();
delete mTcpSocket;
}
// Network Management
bool DataSender::connectToHost(void){
connect(mTcpSocket, SIGNAL(connected()), this, SLOT(onConnect()));
connect(mTcpSocket, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
connect(mTcpSocket, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)));
connect(mTcpSocket, SIGNAL(readyRead()), this, SLOT(onDataReceived()));
qDebug() << "connecting...";
mTcpSocket->setSocketOption(QAbstractSocket::KeepAliveOption, true);
mTcpSocket->connectToHost(getDestinationAddress(), getDestinationPort());
if(!mTcpSocket->waitForConnected(1000))
{
qDebug() << "Error: " << mTcpSocket->errorString();
return false;
}
return true;
}
void DataSender::sendData(void) const{
QByteArray lData("Hello, this is DataSender ! Do you copy ? I repeat, do you copy ?");
QByteArray lTemp;
QDataStream lData2(&lTemp, QIODevice::ReadWrite);
lData2 << lData.size();
if(mTcpSocket->state() == QAbstractSocket::ConnectedState)
{
mTcpSocket->write(lTemp); //write size of data
mTcpSocket->write(lData); //write the data itself
mTcpSocket->waitForBytesWritten();
}
}
// Getters
QString DataSender::getDestinationAddress(void) const{
return mDestinationAddress;
}
unsigned int DataSender::getDestinationPort(void) const{
return mDestinationPort;
}
// Setters
void DataSender::setDestinationAddress(const QString &pDestinationAddress){
mDestinationAddress = pDestinationAddress;
}
void DataSender::setDestinationPort(const unsigned int &pDestinationPort){
mDestinationPort = pDestinationPort;
}
// Public Slots
void DataSender::onConnect(){
qDebug() << "connected...";
}
void DataSender::onDisconnect(){
qDebug() << "disconnected...";
}
void DataSender::onBytesWritten(qint64 bytes){
qDebug() << bytes << " bytes written...";
}
void DataSender::onDataReceived(){
// Not yet implemented, code is for testing
qDebug() << "onDataReceived called !";
//while(mTcpSocket->bytesAvailable()){
//qInfo() << mTcpSocket->read(mTcpSocket->bytesAvailable());
//qDebug() << mTcpSocket->readAll();
//}
}
// Main routine ---------------------------------
int main(int argc, char **argv){
// Initializing application.
QApplication lApplication(argc, argv);
CLIENT::DataReceiver dataReceiver;
dataReceiver.connectToHost();
return lApplication.exec();
}
// Main routine ---------------------------------
int main(int argc, char **argv){
QApplication lApplication(argc, argv);
SERVER::DataSender lDataSender;
lDataSender.connectToHost();
lDataSender.sendData();
return lApplication.exec();
}
基本上,当我在main中运行 DataReceiver 类时,我会得到以下行为:
connecting...
connected...
7 bytes written... # This is the write("Hello ?") I inserted just for testing
# "connected..." may occur after "7 bytes written...",
# I don't remember, I am not in front of my computer right now.
我相信我只是忘记了一些重要的东西,或者说有一些我不知道的东西。这是一个个人项目,所以欢迎一点外部见解!
非常感谢!
Clovel
答案 0 :(得分:0)
QTcpSocket可以与另一个QTcpSocket
进行通信,但为了实现这一点,必须使用client-server model进行初始连接。
QTcpSocket
无法侦听传入连接。相反,QTcpServer
可以使用(或QLocalServer,如果使用QLocalSocket)。
在传入连接的端口上将QTcpSocket
设置为listen,并且在建立连接时,将发出信号以通知newConnection。调用nextPendingConnection会返回服务器端的QTcpSocket
,允许它从传入连接与客户端通信。
答案 1 :(得分:0)
所以这是OP,这是我实施的解决方案。我要感谢@TheDarkKnight&amp; @ G.M。他们的澄清。
我使用了QTcpSocket
AND DataReceiver
的组合,而不是QTcpSocket
类QTcpServer
。基本上,QTcpServer
会监听新的连接和建立连接时设置QTcpSocket
。
然后,班级只需将QTcpSocket
信号readyRead()
连接到个人广告位。以下是该类的实现:
class DataReceiver : QObject
{
Q_OBJECT
public:
// Con/Destructors
explicit DataReceiver(QObject *parent = nullptr);
explicit DataReceiver(const QString &pSourceAddress,
const unsigned int &pSourcePort,
QObject *parent = nullptr);
~DataReceiver();
// Getters
QVector<float> *getData(void) const;
QTcpServer *getTcpServer(void) const;
QString getSourceAddress(void) const;
unsigned int getSourcePort(void) const;
// Setters
void setData(const QVector<float> *pData);
void setSourceAddress(const QString &pSourceAddress);
void setSourcePort(const unsigned int &pSourcePort);
signals:
public slots:
void onConnect();
void onDisconnect();
void onBytesWritten(qint64 bytes);
void onDataReceived();
void onNewConnection();
private:
void decodeData(const QByteArray &pMessage);
QTcpServer *mTcpServer;
QTcpSocket *mTcpSocket;
QString mSourceAddress;
unsigned int mSourcePort;
const unsigned int mDataSize = 30;
QVector<float> *mData;
};
// Con/Destructors
DataReceiver::DataReceiver(QObject *parent) :
QObject(parent),
mTcpServer(new QTcpServer(this)),
mSourceAddress("127.0.0.1"),
mSourcePort(51470),
mData(new QVector<float>)
{
for( unsigned int i = 0; i < mDataSize; i++)
mData->append(.0);
connect(mTcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
if(!mTcpServer->listen(QHostAddress(getSourceAddress()), getSourcePort()))
qDebug() << "<DataReceiver> Server could not start. ";
else
qDebug() << "<DataReceiver> Server started !";
}
DataReceiver::DataReceiver(const QString &pSourceAddress,
const unsigned int &pSourcePort,
QObject *parent) :
QObject(parent),
mTcpServer(new QTcpServer(this)),
mSourceAddress(pSourceAddress),
mSourcePort(pSourcePort),
mData(new QVector<float>)
{
for( unsigned int i = 0; i < mDataSize; i++)
mData->append(.0);
connect(mTcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
if(!mTcpServer->listen(QHostAddress(getSourceAddress())), getSourcePort())
qDebug() << "<DataReceiver> Server could not start. ";
else
qDebug() << "<DataReceiver> Server started !";
}
DataReceiver::~DataReceiver(){
delete mTcpServer;
delete mData;
}
// Getters
QVector<float> *DataReceiver::getData(void) const{
return mData;
}
QTcpServer *DataReceiver::getTcpServer(void) const{
return mTcpServer;
}
QString DataReceiver::getSourceAddress(void) const{
return mSourceAddress;
}
unsigned int DataReceiver::getSourcePort(void) const{
return mSourcePort;
}
// Setters
void DataReceiver::setData(const QVector<float> *pData){
// Not yet implemented
Q_UNUSED(pData);
}
void DataReceiver::setSourceAddress(const QString &pSourceAddress){
mSourceAddress = pSourceAddress;
}
void DataReceiver::setSourcePort(const unsigned int &pSourcePort){
mSourcePort = pSourcePort;
}
// Public Slots
void DataReceiver::onConnect(){
qDebug() << "QTcpSocket connected...";
}
void DataReceiver::onDisconnect(){
qDebug() << "QTcpSocket disconnected...";
disconnect(mTcpSocket, SIGNAL(readyRead()), this, SLOT(onDataReceived()));
disconnect(mTcpSocket, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
}
void DataReceiver::onBytesWritten(qint64 bytes){
qDebug() << bytes << " bytes written to QTcpSocket...";
}
void DataReceiver::onDataReceived(){
// Not yet implemented, code is for testing
qDebug() << "onDataReceived called !";
while(mTcpSocket->bytesAvailable()){
qInfo() << mTcpSocket->read(mTcpSocket->bytesAvailable());
qDebug() << mTcpSocket->readAll();
}
}
void DataReceiver::onNewConnection(){
qDebug() << "onNewConnection called !";
mTcpSocket = mTcpServer->nextPendingConnection();
connect(mTcpSocket, SIGNAL(readyRead()), this, SLOT(onDataReceived()));
connect(mTcpSocket, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
}
// Private Methods
void DataReceiver::decodeData(const QByteArray &pMessage){
// Not yet implemented
Q_UNUSED(pMessage);
}