Note that there are some explanatory texts on larger screens.

plurals
  1. POStreaming images over QTcpSocket on Windows 7
    primarykey
    data
    text
    <p>I am trying to create two test applications based on QTcpSocket, a server that streams (uncompressed) images and a client that receives them.</p> <p>My code is mostly taken from Qts <a href="http://qt-project.org/doc/qt-4.8/network-fortuneclient.html" rel="nofollow">Fortune Client Example</a> and <a href="http://qt-project.org/doc/qt-4.8/network-fortuneserver.html" rel="nofollow">Fortune Server Example</a>. I have cut out all gui. Instead of opening a connection, sending a fortune and then immediately closing it, my server keeps it open and continuously streams my image. The client just reads the images from the QTcpSocket and then discards them.</p> <p>The image I'm sending is 800x600 RGB (=1440000 bytes), I am sending it as often as I am allowed. The image is read from file each time before it is sent and I am not using any compression.</p> <p>The server seems to be sending images just as it should. BUT the client receives them too slowly, 1-4 frames per second, and it seems to not be receiving any data at times, which in turn causes my server to use alot of memory (because the client isn't reading as fast as the server is writing).</p> <p>I've tried running my server and client on different machines and both on one machine, both setups produce the same problem.</p> <p>When running my applications on a Linux machine, the client receives images at a much higher rate (think it was 14 frames per second). The client seems to be able to read as fast as the server writes.</p> <p>Can anyone help shed some light on this problem?</p> <ol> <li>How can I speed up the data transfere? (without using compression)</li> <li>How can I get the client to read as fast as the server is writing?</li> <li>How can I get this to be stable on my Windows machine? (no sudden pauses...) Clicking in the console window of the client sometimes seem to "wake" the application btw. ^^</li> </ol> <p>Here is my code:</p> <p>Server:</p> <p>main.cpp</p> <pre><code>#include &lt;iostream&gt; #include &lt;QCoreApplication&gt; #include "Server.h" int main(int argc, char *argv[]){ QCoreApplication app(argc, argv); QString ipaddress = QString(argv[1]); int port = atoi(argv[2]); Server* server = new Server(ipaddress, port); int retVal = app.exec(); return retVal; } </code></pre> <p>Server.h</p> <pre><code>#ifndef SERVER_H_ #define SERVER_H_ #include &lt;QObject&gt; QT_BEGIN_NAMESPACE class QTcpServer; class QNetworkSession; class QTcpSocket; class QTimer; QT_END_NAMESPACE class Server : public QObject { Q_OBJECT public: Server(QString ipAddress, int port, QObject *parent = 0); private slots: void newConnectionSlot(); void sendSlot(); private: QTcpServer *mTcpServer; QTcpSocket *mTcpSocket; QTimer *mSendTimer; }; #endif /* SERVER_H_ */ </code></pre> <p>Server.cpp</p> <pre><code>#include "Server.h" #include &lt;iostream&gt; #include &lt;QTcpServer&gt; #include &lt;QTcpSocket&gt; #include &lt;QTimer&gt; #include &lt;QDateTime&gt; #include &lt;QSettings&gt; #include &lt;highgui.h&gt; Server::Server(QString ipAddress, int port, QObject *parent) : QObject(parent), mTcpServer(0), mTcpSocket(0) { mTcpServer = new QTcpServer(this); connect(mTcpServer, SIGNAL(newConnection()), this, SLOT(newConnectionSlot())); if (!mTcpServer-&gt;listen(QHostAddress(ipAddress), port)) { std::cout &lt;&lt; "Unable to start the server: " &lt;&lt; mTcpServer-&gt;errorString().toStdString() &lt;&lt; std::endl; return; } std::cout &lt;&lt; "The server is running on\n\nIP: "&lt;&lt; ipAddress.toStdString() &lt;&lt; "\nport: " &lt;&lt; mTcpServer-&gt;serverPort() &lt;&lt; "\n\nRun the Client now.\n" &lt;&lt; std::endl; } void Server::newConnectionSlot() { mTcpSocket = mTcpServer-&gt;nextPendingConnection(); connect(mTcpSocket, SIGNAL(disconnected()), mTcpSocket, SLOT(deleteLater())); // setup timer to send data at a given interval mSendTimer = new QTimer(this); connect(mSendTimer, SIGNAL(timeout()), this, SLOT(sendSlot())); mSendTimer-&gt;start(40); } void Server::sendSlot() { if(!mTcpSocket) return; //know that the image is this big int width = 800; int height = 600; int nChannels = 3; int depth = 8; qint64 blockSize = 1440000; //in bytes qint64 imagesInQue = mTcpSocket-&gt;bytesToWrite()/blockSize; int maxPendingImages = 25; if(imagesInQue &gt; maxPendingImages) { std::cout &lt;&lt; "Dumping." &lt;&lt; std::endl; return; } //load image IplImage* img = cvLoadImage("pic1_24bit.bmp"); if(!img) std::cout &lt;&lt; "Error loading image " &lt;&lt; std::endl;; //send data quint64 written = mTcpSocket-&gt;write(img-&gt;imageData, img-&gt;imageSize); //clean up cvReleaseImage( &amp;img ); } </code></pre> <p>Client:</p> <p>main.cpp</p> <pre><code>#include &lt;iostream&gt; #include &lt;QCoreApplication&gt; #include "Client.h" int main(int argc, char *argv[]){ QCoreApplication app(argc, argv); QString ipaddress = QString(argv[1]); int port = atoi(argv[2]); Client* client = new Client(ipaddress, port); int retVal = app.exec(); } </code></pre> <p>Client.h</p> <pre><code>#ifndef CLIENT_H_ #define CLIENT_H_ #include &lt;QObject&gt; #include &lt;QAbstractSocket&gt; QT_BEGIN_NAMESPACE class QTcpSocket; QT_END_NAMESPACE class Client : public QObject { Q_OBJECT public: Client(QString ipAddress, int port, QObject *parent=0); private slots: void readSlot(); void displayErrorSlot(QAbstractSocket::SocketError); private: QTcpSocket *mTcpSocket; QString mIpAddress; int mPort; }; #endif /* CLIENT_H_ */ </code></pre> <p>Client.cpp</p> <pre><code>#include "Client.h" #include &lt;iostream&gt; #include &lt;QTcpSocket&gt; #include &lt;QSettings&gt; #include &lt;QDateTime&gt; Client::Client(QString ipAddress, int port, QObject *parent): QObject(parent), mTcpSocket(0), mIpAddress(ipAddress), mPort(port) { mTcpSocket = new QTcpSocket(this); connect(mTcpSocket, SIGNAL(readyRead()), this, SLOT(readSlot())); connect(mTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayErrorSlot(QAbstractSocket::SocketError))); std::cout &lt;&lt; "Connecting to ip: " &lt;&lt; mIpAddress.toStdString() &lt;&lt; " port: " &lt;&lt; mPort &lt;&lt; std::endl; mTcpSocket-&gt;connectToHost(mIpAddress, mPort); } void Client::readSlot() { static qint64 starttime = QDateTime::currentMSecsSinceEpoch(); static int frames = 0; //know that the image is this big int width = 800; int height = 600; int nChannels = 3; int depth = 8; qint64 blockSize = 1440000; //in bytes if (mTcpSocket-&gt;bytesAvailable() &lt; blockSize) { return; } frames++; char* data = (char*) malloc(blockSize+100); qint64 bytesRead = mTcpSocket-&gt;read(data, blockSize); free(data); //FPS if(frames % 100 == 0){ float fps = frames/(QDateTime::currentMSecsSinceEpoch() - starttime); std::cout &lt;&lt; "FPS: " &lt;&lt; fps &lt;&lt; std::endl; } } void Client::displayErrorSlot(QAbstractSocket::SocketError socketError) { switch (socketError) { case QAbstractSocket::RemoteHostClosedError: break; case QAbstractSocket::HostNotFoundError: std::cout &lt;&lt; "The host was not found. Please check the " "host name and port settings."&lt;&lt; std::endl; break; case QAbstractSocket::ConnectionRefusedError: std::cout &lt;&lt; "The connection was refused by the peer. " "Make sure the fortune server is running, " "and check that the host name and port " "settings are correct."&lt;&lt; std::endl; break; default: std::cout &lt;&lt; "The following error occurred: " &lt;&lt; mTcpSocket-&gt;errorString().toStdString() &lt;&lt; std::endl; break; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload