do multiple calls to write of QTcpSocket/QWebSocket overwrite previous bytes which are not yet written?
-
hello there. sorry to bother you again.
I have a few questions about QTcpSocket and QWebSocketWhen the write function of QTcpSocket is called, it doesn't write all bytes instantaneously but stores it in some sort of buffer, right? So When I call write multiple times while there are still some bytes to be written, are previous bytes which are not yet written are overwritten?
Also, multiple calls to sendBinaryMessage of QWebSocket overwrite previous bytes which are not yet written?
if bytes are not overwritten then in which order does the QByteArray objects are read by the client ? for example in the following situation on the server with QWebSocket
socket.sendBinaryMessage(MyQByteArray1); socket.sendBinaryMessage(MyQByteArray2); socket.sendBinaryMessage(MyQByteArray3);
will binaryMessageReceived signals contain QByteArray objects which are the same as those on the server-side in sequence? something like?
binaryMessageReceived(MyQByteArray1); binaryMessageReceived(MyQByteArray2); binaryMessageReceived(MyQByteArray3);
or do they arrive in random order?
-
Hi,
I done some testing with QWebSocket and QWebSocketServer. basically I send 3 Images from client to server of the following size 5 times without waiting for bytes to write$ du -h *.jpg 35M c0.jpg 56K c1.jpg 30M c.jpg
client.cpp:-
#include <QApplication> #include <QImage> #include <QWebSocket> #include <QDataStream> #include <QLabel> #include <QAbstractSocket> #include <QFile> void onConnected(QWebSocket *socket,QString str){ QFile imgfile(str); imgfile.open(QIODevice::ReadOnly); QByteArray buf; QDataStream stream(&buf,QIODevice::WriteOnly); socket->sendBinaryMessage(imgfile.readAll()); socket->flush(); } int main(int argc, char *argv[]) { QApplication a(argc, argv); QWebSocket *socket = new QWebSocket; socket->open(QUrl("ws://127.0.0.1:1718")); QObject::connect(socket, &QWebSocket::disconnected, [socket]() { qDebug() << socket->errorString(); }); QObject::connect(socket,&QWebSocket::connected,[socket]{ for(int i=0; i<5;i++){ onConnected(socket,"c.jpg"); onConnected(socket,"c0.jpg"); onConnected(socket,"c1.jpg"); } }); return a.exec(); }
server.cpp:-
#include <QApplication> #include <QWebSocket> #include <QHostAddress> #include <QWebSocketServer> #include <QLabel> #include <QFile> int main(int argc, char *argv[]) { QApplication a(argc, argv); QWebSocketServer server(QStringLiteral("My server"),QWebSocketServer::SslMode::NonSecureMode); if(!server.listen(QHostAddress::Any,1718)){ qDebug() << server.errorString() ; return -1; } qDebug() << server.serverUrl().toString(); QObject::connect(&server, &QWebSocketServer::newConnection,[&server](){ static int i=100; qDebug() << "new connection"; QWebSocket *pSocket = server.nextPendingConnection(); QObject::connect(pSocket, &QWebSocket::binaryMessageReceived, [](const QByteArray &rawimg){ auto img = QImage::fromData(rawimg,"JPG"); QLabel *myLabel = new QLabel; myLabel->setPixmap(QPixmap::fromImage(img)); myLabel->show(); QFile file(QString::number(i++)); file.open(QFile::WriteOnly); file.write(rawimg); }); }); return a.exec(); }
When I run this program, I can see with the help of title name <server*> of windows and new images in server directory, that images are displayed and written on disk in order in which they were sent from the client.
This marks my original question answered. So I am marking this as solved
But btw when I ran server and client, something weird happened.
when I ran server and client, my laptop became unresponsive for a minute. I couldn't even reach tty to kill server and client. the audio was still playing in the meantime. after a minute, it became responsive again. Then I killed the server and client and got this (I always leave it running in background) :-it nearly filled my RAM and on top of that, it also consumed 6GB of the swap. my swap doesn't even get filled with 1KB normally. is this normal ? am I doing something wrong?
-
@noone said in do multiple calls to write of QTcpSocket/QWebSocket overwrite previous bytes which are not yet written?:
So When I call write multiple times while there are still some bytes to be written, are previous bytes which are not yet written are overwritten?
No, why should this happen?
-
@Christian-Ehrlicher I guess this should not happen. So I should not write until the previous bytes is written? I am really new this stuff and so much confused
-
Hi
On most devices, the sending buffer (in the network layer) is big enough
that you should never have to worry about that and just send as you like.
It should never overwrite anything.The things you send will/should come in the same order as when you send it.
-
@noone
Yes I would think so unless the WebSocket protocol has some limitation which i think the docs would
have mentioned then. Or maybe if your message is extremely huge. -
if your message is extremely huge.
I want to send some data from the QSqlDatabase along with multiple (Q)images, they might be in KBs or In MBs. If I serialize multiple QImages with QDatastream then it would easily become more than ~20MB
-
@noone
Hi
That should work fine.
I'm not that familiar with WebSocket protocol if it also will issue multiple
binaryMessageReceived signal pr message if the message is large or if that is handled internally and will first trigger binaryMessageReceived signal when all is received.
You should test it out with one and see. -
Hi,
I done some testing with QWebSocket and QWebSocketServer. basically I send 3 Images from client to server of the following size 5 times without waiting for bytes to write$ du -h *.jpg 35M c0.jpg 56K c1.jpg 30M c.jpg
client.cpp:-
#include <QApplication> #include <QImage> #include <QWebSocket> #include <QDataStream> #include <QLabel> #include <QAbstractSocket> #include <QFile> void onConnected(QWebSocket *socket,QString str){ QFile imgfile(str); imgfile.open(QIODevice::ReadOnly); QByteArray buf; QDataStream stream(&buf,QIODevice::WriteOnly); socket->sendBinaryMessage(imgfile.readAll()); socket->flush(); } int main(int argc, char *argv[]) { QApplication a(argc, argv); QWebSocket *socket = new QWebSocket; socket->open(QUrl("ws://127.0.0.1:1718")); QObject::connect(socket, &QWebSocket::disconnected, [socket]() { qDebug() << socket->errorString(); }); QObject::connect(socket,&QWebSocket::connected,[socket]{ for(int i=0; i<5;i++){ onConnected(socket,"c.jpg"); onConnected(socket,"c0.jpg"); onConnected(socket,"c1.jpg"); } }); return a.exec(); }
server.cpp:-
#include <QApplication> #include <QWebSocket> #include <QHostAddress> #include <QWebSocketServer> #include <QLabel> #include <QFile> int main(int argc, char *argv[]) { QApplication a(argc, argv); QWebSocketServer server(QStringLiteral("My server"),QWebSocketServer::SslMode::NonSecureMode); if(!server.listen(QHostAddress::Any,1718)){ qDebug() << server.errorString() ; return -1; } qDebug() << server.serverUrl().toString(); QObject::connect(&server, &QWebSocketServer::newConnection,[&server](){ static int i=100; qDebug() << "new connection"; QWebSocket *pSocket = server.nextPendingConnection(); QObject::connect(pSocket, &QWebSocket::binaryMessageReceived, [](const QByteArray &rawimg){ auto img = QImage::fromData(rawimg,"JPG"); QLabel *myLabel = new QLabel; myLabel->setPixmap(QPixmap::fromImage(img)); myLabel->show(); QFile file(QString::number(i++)); file.open(QFile::WriteOnly); file.write(rawimg); }); }); return a.exec(); }
When I run this program, I can see with the help of title name <server*> of windows and new images in server directory, that images are displayed and written on disk in order in which they were sent from the client.
This marks my original question answered. So I am marking this as solved
But btw when I ran server and client, something weird happened.
when I ran server and client, my laptop became unresponsive for a minute. I couldn't even reach tty to kill server and client. the audio was still playing in the meantime. after a minute, it became responsive again. Then I killed the server and client and got this (I always leave it running in background) :-it nearly filled my RAM and on top of that, it also consumed 6GB of the swap. my swap doesn't even get filled with 1KB normally. is this normal ? am I doing something wrong?
-
Hi
It sounds like you have a memory leak somewhere.Things like
QLabel *myLabel = new QLabel; << you assign it no parent so it won't be deleted by the parent.You could use
myLabel->setAttribute(Qt::WA_DeleteOnClose);If it pops up the image and you close it by pressing X
Its should not normally use all your memory and 6GB swap :)
oh, the image is 35M !!!
ok so I guess its just the QLabel not being deleted and it gets a copy of the image so
you dont have to send those 3 images many times to eat lots of memory :) -
after removing the lines:-
auto img = QImage::fromData(rawimg); QLabel *myLabel = new QLabel; myLabel->setPixmap(QPixmap::fromImage(img)); myLabel->show();
it works perfectly with more than 20*3 images
3/11