How to send images through socket
-
I would like to send a few images to the client and the code as the following
QTcpSocket *socket = server->nextPendingConnection(); sockets.append(socket); QImage *pic = new QImage (":/movies/now_showing/bohemian.png"); QByteArray ba; QBuffer buffer(&ba); pic->save(&buffer, "PNG"); qDebug()<<ba; socket->flush(); socket->write(ba); socket->waitForBytesWritten(); socket->flush(); ba.clear();
this is the code for server but I still having a few images would like to send then I tried with the repeating things like
QImage *pic1 = new QImage (":/movies/now_showing/grinch.png"); QBuffer buffer1(&ba); pic1->save(&buffer1, "PNG"); qDebug()<<ba; socket->flush(); socket->write(ba); socket->waitForBytesWritten(); socket->flush();
and in the client with the code as follow:
QBuffer *imgb = new QBuffer(); imgb->open(QIODevice::ReadWrite); socket->waitForReadyRead(1); QByteArray temp; temp = socket->readAll(); imgb->write(temp); QImage pic; pic.loadFromData(imgb->buffer()); if(!pic.isNull()) { qDebug() << "Image file was received "; qDebug() << "size = " << temp.size(); }else{ qDebug() << "Pic is NULL"; qDebug() << "size = " << temp.size(); } QPixmap p1(QPixmap::fromImage(pic)); QIcon p2(p1); ui->poster_1->setIcon(p2); ui->poster_1->setIconSize(p1.rect().size()); ui->poster_1->raise();
then I repeated for the second picture as
QBuffer *imgb1 = new QBuffer(); imgb1->open(QIODevice::ReadWrite); socket->waitForReadyRead(1); QByteArray temp1; temp1 = socket->readAll(); imgb1->write(temp1); QImage pic3; pic3.loadFromData(imgb1->buffer()); if(!pic3.isNull()) { qDebug() << "Image file was received "; qDebug() << "size = " << temp1.size(); }else{ qDebug() << "Pic is NULL"; qDebug() << "size = " << temp1.size(); } QPixmap p4(QPixmap::fromImage(pic3)); QIcon p3(p4); ui->poster_2->setIcon(p3); ui->poster_2->setIconSize(p4.rect().size()); ui->poster_2->raise();
but it will only shown the second image sent from server. How can I send a few images also how to send a large image to client through socket ?
Thanks for helping ! -
@greencow said in How to send images through socket:
temp = socket->readAll();
This will not necessarily return the whole picture, because TCP/IP sends data in packages and you do not know how many packages you will get until you got everything.
-
-
There is nothing special about/no relevance to whether you send "images" or anything else. Sockets just transfer binary bytes, what they mean/what you do with them is quite outside its scope.
-
Sockets are a streaming protocol, not a "record-based" one. Although you might write 1 byte or a million bytes from the sender, they do not arrive as the corresponding 1 byte or a million bytes at the receiver. Instead, basically "chunks" appear at the receiver over time.
So, although you send all the bytes in one go from the sender, doing one
waitForReadyRead()/readAll()
is not good enough. You are assuming that will read the entirety of what the server sent, but it (probably) won't. You need to loop repeatedly callingwaitForReadyRead()/readAll()
to get all the data. (Much) Better, use the socket's slots for bytes available & read bytes to continuously pick up & build the data arriving.Also, although you know you have sent two images one after the other, your client will not know that at all. It will not recognise where one image's bytes end and the next image's bytes begin. Basically, in some shape or form your server needs to send something (at the start of an image transfer) to tell the client how many bytes to expect, then the client needs to read that many bytes. Look at http://doc.qt.io/qt-5/qdatastream.html and particularly http://doc.qt.io/qt-5/qdatastream.html#using-read-transactions to help you.
-