read tcpsocket by qt - c++

hi i want to receive data from FPGA by Ethernet with qt. i can write data to fpga but unfortunately i cant receive data. after writing x"c000" to fpga it should send data but my code doesn't woked.
i write this code for receive data but i cant please help me.
QByteArray ba2;
ba2.resize(2);
ba2[0] = 0x00;
ba2[1] = 0xc0;
Client ob;
ob.connectToHost();
ob.writeData(ba2);
QByteArray Client:: readback(QByteArray data)
{
qDebug() << socket->readAll();
return data;
}
void Client::connectToHost()
{
socket->connectToHost("192.168.100.17", 1134);
}
void Client::close()
{
socket->close();
}
Client::Client(QObject *parent) : QObject(parent)
{
socket = new QTcpSocket();
connect(socket, SIGNAL(readyRead()), this, SLOT(readback(QByteArray data)));
}

Try it asynch:
auto t = make_unique<QTcpSocket>();
QObject::connect(t.data(),&QTcpSocket::connected,[&t](){
QDataStream writer(t.data());
writer << static_cast<quint16>(0xc000);
});
QObject::connect(t.data(),&QTcpSocket::readyRead,[&t](){
qDebug() << t->readAll();
});

Related

QAudioOutput doesn't work correctly. I hear only noise

my program capture raw data from microphone in QT.
QAudioRecorder* recorder = new QAudioRecorder();
QAudioProbe* probe = new QAudioProbe;
connect(probe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(processBuffer(QAudioBuffer)));
QAudioEncoderSettings audioSettings;
audioSettings.setCodec("audio/mpeg");
audioSettings.setQuality(QMultimedia::HighQuality);
recorder->setEncodingSettings(audioSettings);
qDebug() << "probe ritorna " << probe->setSource(recorder); // Returns true, hopefully.
//qDebug() << "" << recorder->setOutputLocation(QUrl::fromLocalFile("test"));
recorder->record(); // Now we can do things like calculating levels or performing an FFT
myAudioServer = new MyAudioServer();
myAudioServer->startServer();
In previous code I record audio and I start a Qthread for send audio via QTcpSocket.
void QtVideoWidgetsIssueTrack::processBuffer(const QAudioBuffer& buffer){
QByteArray byteArr;
byteArr.append(buffer.constData<char>(), buffer.byteCount());
QByteArray Data = byteArr;
qDebug() << myAudioServer->isListening();
QTcpSocket* myAudioClient = myAudioServer->getSocket();
qDebug() << myAudioClient;
qDebug() << "in processBuffer";
if (myAudioClient != nullptr) {
myAudioClient->write(Data, Data.count());
myAudioClient->waitForBytesWritten();
}
}
The method processBuffer take data from microphone and send it from server to client.
void MyThreadAudioTcpSocket::readyRead()
{
while (socket->bytesAvailable() > 0) {
//fare il play da QByteArray
// get default output device
QByteArray* yourSoundData = new QByteArray(socket->readAll());
QBuffer* buffer = new QBuffer;
buffer->setData(yourSoundData->data(),yourSoundData->size());
buffer->open(QBuffer::ReadOnly);
QAudioFormat format;
format.setSampleSize(16);
format.setSampleRate(22050);
format.setChannelCount(1);
format.setCodec("audio/mpeg");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
if (!info.isFormatSupported(format)) {
format = info.nearestFormat(format);
qDebug() << "formato non supportato";
}
QAudioOutput *output = new QAudioOutput(format);
output->moveToThread(this);
output->start(buffer);
}
}
readyRead is where data arrive from socket server. I read all data from socket, I put it in Buffer, set QAudioFormat and I create QAudioOutput linked buffer and start.
Now as you can hear from this link wav file QAudioOutput produce only noise. Why?

QSerialPort readings refresh too fast for the Qt widget

I am using QSerialPort to read from a device connected to a COM port on my computer, and it sends characters every half a second to my computer. I can read them from the qDebug window, so I know the connection works and Qt receives the data.
However I continuously read from the serial port and refresh a label widget on my GUI. The label becomes blank when I run the app, I think this problem is caused by the label name constantly refreshing.
My QserialPort is managed in the mainwindow constructor, closed in destructor, and the readings are done in a function called serialReceived(), which I believe is called (or causes the label to refresh) too often
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
serial = new QSerialPort(this);
qDebug() << "nb ports: " << QSerialPortInfo::availablePorts().length();
foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts())
{
qDebug() << "name" << serialPortInfo.portName();
}
serial->setPortName("COM11");
serial->setBaudRate(QSerialPort::Baud9600);
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
qDebug() << "is " << serial->open(QSerialPort::ReadOnly);
qDebug() << "err " << serial->error();
//serial->write("ok");
// Create the signal and slot
connect(serial, SIGNAL(readyRead()), this, SLOT(serialReceived()));
}
MainWindow::~MainWindow()
{
delete ui;
serial->close(); // instance is closed when mainwindow destroyed
}
void MainWindow::serialReceived()
{
QByteArray ba;
ba = serial->readAll();
ui->label->setText(serial->readAll());
qDebug()<<ba;
}
void MainWindow::serialReceived()
{
QByteArray ba;
ba = serial->readAll();
ui->label->setText(serial->readAll());
qDebug()<<ba;
}
You're first reading the data into ba, then you try to read again but since readAll() already read the data there is nothing left. You want
void MainWindow::serialReceived()
{
QByteArray ba = serial->readAll();
ui->label->setText(ba);
qDebug() << ba;
}
You just can read data at any time you want, not only by readyRead signal. The QSerialPort class will buffer all received data until you read it.
You also can append every received part of data to some scrollable QPlainTextEdit. I recommend this way.
void MainWindow::serialReceived()
{
QByteArray ba;
ba = serial->readAll();
ui->plainTextEdit->appendPlainText(ba);
}
Using timer:
connect(&m_timer, &QTimer::timeout, this, &MyClass::onTimer);
...
m_timer->start(5000);
...
void MyClass::onTimer()
{
if(serial->bytesAvailable() > 0)
{
QByteArray ba;
ba = serial->readAll();
ui->label->setText(ba);
qDebug() << ba;
}
}
You can also temporary disable visual updates of a widget using QWidget::setUpdatesEnabled(), but seems you should not miss part of the data.
Be note, QIODevice (and QSerialPort as its sublass, too) class makes no guarantee that a certain amount of data will be available on the readyRead event. For example, if you wrote 10 bytes to the port at a time on the other end, in some cases you will receive the signal that will allow less data to be available at the monent, that is, before all the transmitted bytes arrives.

How can i write the serial port incoming data into text file (.txt)

How I can write the serial port incoming data into text file(.txt).. The data write should have one hour interval time.
Following this the serial read data code:
void MainWindow::readData()
{
QByteArray data = serial->readAll();
QDataStream stream(data);
double value;
stream>>value;
console->putData(data);
qDebug()<<value;
}
I have tried this way but failed
void Write(QString Filename)
{
QFile mFile(Filename);
if(!mFile.open(QFile::WriteOnly | QFile::Text))
{
qDebug() << "Could not open file for writing";
return;
}
QTextStream out(&mFile);
out << data;
mFile.flush();
mFile.close();
}
I suggest you to use QByteArray for receiving and use signal readyRead() to call receive function when data is received.
QSerialPort *serialPort= new QSerialPort();
connect(serialPort, &QSerialPort::readyRead, this, &MainWindow::receiveData_WriteToFile);
This function read data and write it in file.
void MainWindow::receiveData_WriteToFile()
{
if (serialPort->isOpen())
{
QByteArray DataReceived;
QFile LogFile("D:/data.txt");
if(!LogFile.open(QFile::Append | QFile::Text))
{
//Can't Open Log File.
}
if(serialPort->bytesAvailable())
{
DataReceived = serialPort->readAll();//All Data Received Successfully.
if(DataReceived.size() > 0)
{
if(LogFile.isOpen())
{
QTextStream in(&LogFile);
in << DataReceived;
}
LogFile.close();
}
else
{
//Fail To Receive Data.
}
}
LogFile.close();
}
}
readyRead() : This signal is emitted once every time new data is available for reading from the device's current read channel. It will only be emitted again once new data is available, such as when a new payload of network data has arrived on your network socket, or when a new block of data has been appended to your device.
output file:
This is a sample project for your question on github download here.

Why QTcpSocket doesn't write ? I need to flush it to make it send my data

I read in the documentation that to send a packet with QTcpSocket I can just use the write method.
But when I do it, my server doesn't receive it. I need to call flush or waitForByteWritten to send it.
TCPClient::TCPClient(Client *babel , const std::string &hostname, unsigned short port, QObject *parent) : QObject(parent), client(babel), hostName(hostname), port(port), is_connected(false)
{
this->tcpSocket = new QTcpSocket(this);
connect(this->tcpSocket, SIGNAL(readyRead()),this, SLOT(readMessage()));
connect(this->tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
connect(this->tcpSocket, SIGNAL(connected()), this, SLOT(connectReady()));
connect(this->tcpSocket, SIGNAL(disconnected()), this, SLOT(disconnectedReady()));
}
TCPClient::~TCPClient()
{
}
bool TCPClient::initiateService()
{
this->tcpSocket->connectToHost(this->hostName.c_str(), this->port);
this->tcpSocket->waitForConnected(5000);
}
void TCPClient::connectReady()
{
this->is_connected = true;
}
void TCPClient::disconnectedReady()
{
}
bool TCPClient::sendBabelPacket(Protocol::BabelPacket &packet)
{
if(this->tcpSocket->state() == QAbstractSocket::ConnectedState && is_connected)
{
std::cout << "writing ... size : " << sizeof(Protocol::BabelPacket) + packet.dataLength<<std::endl;
this->tcpSocket->write((const char *)&packet, sizeof(Protocol::BabelPacket) + packet.dataLength);
//this->tcpSocket->flush();
return true;
}
else
{
std::cout << "socket close" << std::endl;
return false;
}
}
void TCPClient::shutDown()
{
this->tcpSocket->abort();
}
void TCPClient::displayError(QAbstractSocket::SocketError socketError)
{
}
void TCPClient::readMessage()
{
char buffer[sizeof(Protocol::BabelPacket)];
this->tcpSocket->read(buffer, sizeof(Protocol::BabelPacket));
}
When I call write, it returns the right amount of bytes.
I use this class in a GUI context, in the same thread.
QTcpSocket is a buffered device, so data is not written directly, but into internal buffer. Documentation states:
Note: TCP sockets cannot be opened in QIODevice::Unbuffered mode.
Because of it you should call flush or waitForBytesWritten to be sure something is transferred.
There is the difference between them. flush writes as much as possible from the internal write buffer to the underlying network socket, without blocking. waitForBytesWritten blocks until at least one byte has been written on the socket and the bytesWritten() signal has been emitted.

Client Server program in qt

I am new in Qt, I want to write a simple client server program that client send a message to server and server get it and send it back to client.I wrote the server program but i have problem in client and I don't know how should I write it. could you please help me?
Here is my client code:
#include "myclient.h"
#include "QTcpsocket"
#include "QTcpServer"
#include "mainwindow.h"
Client::Client(QObject* parent): QObject(parent)
{
connect(&client, SIGNAL(connected()),this, SLOT(sendData()),Qt::DirectConnection);
}
void myclient::attemptConnection()
{
connect(QTcpSocket, SIGNAL(newConnection()), this, SLOT(connectionAccepted()));
if(QTcpSocket->listen("127.0.0.1",1234))
{
qDebug() << "Server listening";
}
else
{
qDebug() << "Couldn't listen to port" << server->serverPort() << ":" << server->errorString();
}
}
void myclient::connect()
{
QTcpSocket->connectToHost(LocalHost,1234,QIODevice::ReadWrite);
if(QTcpSocket->waitForConnected())
{
QString string = "Hello";
QByteArray array;
array.append(string);
qDebug()<<QTcpSocket->write(array);
}
else
{
qDebug() << "couldn't connect";
}
}
QTcpSocket socket;
void myclient::connectionAccepted()
{
qDebug()<<"Connected";
connect(socket, SIGNAL(readyRead()), this, SLOT(readSocket()));
}
void myclient::readSocket()
{
qDebug()<<socket->readBufferSize();
QByteArray = socket->readAll();
}
I think You Should take A look at the Forutne Client Example From Qt Docs, And base your code on it.
In your code you are using Both Blocking Functions from the waitFor*(), And Non-Blocking signals/slots (readyRead() signal), The Non-Blocking approach is Highly recommended (especially if the code is executed in the GUI thread).
Also I am not sure about your function attemptConnection, which uses newConnection() signal, new Connection is not even a member of QTcpSocket.