Sophie

Sophie

distrib > Mageia > 7 > x86_64 > by-pkgid > 1dd17e0d683ef79b4bb6872bbf359d7f > files > 4094

qt4-doc-4.8.7-26.2.mga7.noarch.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- fortuneclient.qdoc -->
  <title>Qt 4.8: Fortune Client Example</title>
  <link rel="stylesheet" type="text/css" href="style/style.css" />
  <script src="scripts/jquery.js" type="text/javascript"></script>
  <script src="scripts/functions.js" type="text/javascript"></script>
  <link rel="stylesheet" type="text/css" href="style/superfish.css" />
  <link rel="stylesheet" type="text/css" href="style/narrow.css" />
  <!--[if IE]>
<meta name="MSSmartTagsPreventParsing" content="true">
<meta http-equiv="imagetoolbar" content="no">
<![endif]-->
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie6.css">
<![endif]-->
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie7.css">
<![endif]-->
<!--[if IE 8]>
<link rel="stylesheet" type="text/css" href="style/style_ie8.css">
<![endif]-->

<script src="scripts/superfish.js" type="text/javascript"></script>
<script src="scripts/narrow.js" type="text/javascript"></script>

</head>
<body class="" onload="CheckEmptyAndLoadList();">
 <div class="header" id="qtdocheader">
    <div class="content"> 
    <div id="nav-logo">
      <a href="index.html">Home</a></div>
    <a href="index.html" class="qtref"><span>Qt Reference Documentation</span></a>
    <div id="narrowsearch"></div>
    <div id="nav-topright">
      <ul>
        <li class="nav-topright-home"><a href="http://qt.digia.com/">Qt HOME</a></li>
        <li class="nav-topright-dev"><a href="http://qt-project.org/">DEV</a></li>
        <li class="nav-topright-doc nav-topright-doc-active"><a href="http://qt-project.org/doc/">
          DOC</a></li>
        <li class="nav-topright-blog"><a href="http://blog.qt.digia.com/">BLOG</a></li>
      </ul>
    </div>
    <div id="shortCut">
      <ul>
        <li class="shortCut-topleft-inactive"><span><a href="index.html">Qt 4.8</a></span></li>
        <li class="shortCut-topleft-active"><a href="http://qt-project.org/doc/">ALL VERSIONS        </a></li>
      </ul>
     </div>
 <ul class="sf-menu" id="narrowmenu"> 
             <li><a href="#">API Lookup</a> 
                 <ul> 
                     <li><a href="classes.html">Class index</a></li> 
           <li><a href="functions.html">Function index</a></li> 
           <li><a href="modules.html">Modules</a></li> 
           <li><a href="namespaces.html">Namespaces</a></li> 
           <li><a href="qtglobal.html">Global Declarations</a></li> 
           <li><a href="qdeclarativeelements.html">QML elements</a></li> 
             </ul> 
             </li> 
             <li><a href="#">Qt Topics</a> 
                 <ul> 
                        <li><a href="qt-basic-concepts.html">Programming with Qt</a></li>  
                        <li><a href="qtquick.html">Device UIs &amp; Qt Quick</a></li>  
                        <li><a href="qt-gui-concepts.html">UI Design with Qt</a></li>  
                        <li><a href="supported-platforms.html">Supported Platforms</a></li>  
                        <li><a href="technology-apis.html">Qt and Key Technologies</a></li>  
                        <li><a href="best-practices.html">How-To's and Best Practices</a></li>  
              </ul> 
                 </li> 
                 <li><a href="#">Examples</a> 
                     <ul> 
                       <li><a href="all-examples.html">Examples</a></li> 
                       <li><a href="tutorials.html">Tutorials</a></li> 
                       <li><a href="demos.html">Demos</a></li> 
                       <li><a href="qdeclarativeexamples.html">QML Examples</a></li> 
                </ul> 
                     </li> 
                 </ul> 
    </div>
  </div>
  <div class="wrapper">
    <div class="hd">
      <span></span>
    </div>
    <div class="bd group">
      <div class="sidebar">
        <div class="searchlabel">
          Search index:</div>
        <div class="search" id="sidebarsearch">
          <form id="qtdocsearch" action="" onsubmit="return false;">
            <fieldset>
              <input type="text" name="searchstring" id="pageType" value="" />
 <div id="resultdialog"> 
 <a href="#" id="resultclose">Close</a> 
 <p id="resultlinks" class="all"><a href="#" id="showallresults">All</a> | <a href="#" id="showapiresults">API</a> | <a href="#" id="showarticleresults">Articles</a> | <a href="#" id="showexampleresults">Examples</a></p> 
 <p id="searchcount" class="all"><span id="resultcount"></span><span id="apicount"></span><span id="articlecount"></span><span id="examplecount"></span>&nbsp;results:</p> 
 <ul id="resultlist" class="all"> 
 </ul> 
 </div> 
            </fieldset>
          </form>
        </div>
        <div class="box first bottombar" id="lookup">
          <h2 title="API Lookup"><span></span>
            API Lookup</h2>
          <div  id="list001" class="list">
          <ul id="ul001" >
              <li class="defaultLink"><a href="classes.html">Class index</a></li>
              <li class="defaultLink"><a href="functions.html">Function index</a></li>
              <li class="defaultLink"><a href="modules.html">Modules</a></li>
              <li class="defaultLink"><a href="namespaces.html">Namespaces</a></li>
              <li class="defaultLink"><a href="qtglobal.html">Global Declarations</a></li>
              <li class="defaultLink"><a href="qdeclarativeelements.html">QML elements</a></li>
            </ul> 
          </div>
        </div>
        <div class="box bottombar" id="topics">
          <h2 title="Qt Topics"><span></span>
            Qt Topics</h2>
          <div id="list002" class="list">
            <ul id="ul002" >
               <li class="defaultLink"><a href="qt-basic-concepts.html">Programming with Qt</a></li> 
               <li class="defaultLink"><a href="qtquick.html">Device UIs &amp; Qt Quick</a></li> 
               <li class="defaultLink"><a href="qt-gui-concepts.html">UI Design with Qt</a></li> 
               <li class="defaultLink"><a href="supported-platforms.html">Supported Platforms</a></li>  
               <li class="defaultLink"><a href="technology-apis.html">Qt and Key Technologies</a></li> 
               <li class="defaultLink"><a href="best-practices.html">How-To's and Best Practices</a></li> 
            </ul>  
          </div>
        </div>
        <div class="box" id="examples">
          <h2 title="Examples"><span></span>
            Examples</h2>
          <div id="list003" class="list">
        <ul id="ul003">
              <li class="defaultLink"><a href="all-examples.html">Examples</a></li>
              <li class="defaultLink"><a href="tutorials.html">Tutorials</a></li>
              <li class="defaultLink"><a href="demos.html">Demos</a></li>
              <li class="defaultLink"><a href="qdeclarativeexamples.html">QML Examples</a></li>
            </ul> 
          </div>
        </div>
      </div>
      <div class="wrap">
        <div class="toolbar">
          <div class="breadcrumb toolblock">
            <ul>
              <li class="first"><a href="index.html">Home</a></li>
              <!--  Breadcrumbs go here -->
<li><a href="all-examples.html">Examples</a></li>
<li>Fortune Client Example</li>
            </ul>
          </div>
          <div class="toolbuttons toolblock">
            <ul>
              <li id="smallA" class="t_button">A</li>
              <li id="medA" class="t_button active">A</li>
              <li id="bigA" class="t_button">A</li>
              <li id="print" class="t_button"><a href="javascript:this.print();">
                <span>Print</span></a></li>
            </ul>
        </div>
        </div>
        <div class="content mainContent">
<h1 class="title">Fortune Client Example</h1>
<span class="subtitle"></span>
<!-- $$$network/fortuneclient-description -->
<div class="descr"> <a name="details"></a>
<p>Files:</p>
<ul>
<li><a href="network-fortuneclient-client-cpp.html">network/fortuneclient/client.cpp</a></li>
<li><a href="network-fortuneclient-client-h.html">network/fortuneclient/client.h</a></li>
<li><a href="network-fortuneclient-main-cpp.html">network/fortuneclient/main.cpp</a></li>
<li><a href="network-fortuneclient-fortuneclient-pro.html">network/fortuneclient/fortuneclient.pro</a></li>
</ul>
<p>The Fortune Client example shows how to create a client for a simple network service using <a href="qtcpsocket.html">QTcpSocket</a>.<p>The example is intended to be run alongside the <a href="network-fortuneserver.html">Fortune Server</a> example or the <a href="network-threadedfortuneserver.html">Threaded Fortune Server</a> example.</p>
<p class="centerAlign"><img src="images/fortuneclient-example.png" alt="Screenshot of the Fortune Client example" /></p><p>This example uses a simple <a href="qdatastream.html">QDataStream</a>-based data transfer protocol to request a line of text from a fortune server (from the <a href="network-fortuneserver.html">Fortune Server</a> example). The client requests a fortune by simply connecting to the server. The server then responds with a 16-bit (quint16) integer containing the length of the fortune text, followed by a <a href="qstring.html">QString</a>.</p>
<p><a href="qtcpsocket.html">QTcpSocket</a> supports two general approaches to network programming:</p>
<ul>
<li><i>The asynchronous (non-blocking) approach.</i> Operations are scheduled and performed when control returns to Qt's event loop. When the operation is finished, <a href="qtcpsocket.html">QTcpSocket</a> emits a signal. For example, <a href="qabstractsocket.html#connectToHost">QTcpSocket::connectToHost</a>() returns immediately, and when the connection has been established, <a href="qtcpsocket.html">QTcpSocket</a> emits <a href="qabstractsocket.html#connected">connected()</a>.</li>
<li><i>The synchronous (blocking) approach.</i> In non-GUI and multithreaded applications, you can call the <tt>waitFor..&#x2e;()</tt> functions (e.g&#x2e;, <a href="qabstractsocket.html#waitForConnected">QTcpSocket::waitForConnected</a>()) to suspend the calling thread until the operation has completed, instead of connecting to signals.</li>
</ul>
<p>In this example, we will demonstrate the asynchronous approach. The <a href="network-blockingfortuneclient.html">Blocking Fortune Client</a> example illustrates the synchronous approach.</p>
<p>Our class contains some data and a few private slots:</p>
<pre class="cpp"> <span class="keyword">class</span> Client : <span class="keyword">public</span> <span class="type"><a href="qdialog.html">QDialog</a></span>
 {
     Q_OBJECT

 <span class="keyword">public</span>:
     Client(<span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>parent <span class="operator">=</span> <span class="number">0</span>);

 <span class="keyword">private</span> <span class="keyword">slots</span>:
     <span class="type">void</span> requestNewFortune();
     <span class="type">void</span> readFortune();
     <span class="type">void</span> displayError(<span class="type"><a href="qabstractsocket.html">QAbstractSocket</a></span><span class="operator">::</span>SocketError socketError);
     <span class="type">void</span> enableGetFortuneButton();
     <span class="type">void</span> sessionOpened();

 <span class="keyword">private</span>:
     <span class="type"><a href="qlabel.html">QLabel</a></span> <span class="operator">*</span>hostLabel;
     <span class="type"><a href="qlabel.html">QLabel</a></span> <span class="operator">*</span>portLabel;
     <span class="type"><a href="qlineedit.html">QLineEdit</a></span> <span class="operator">*</span>hostLineEdit;
     <span class="type"><a href="qlineedit.html">QLineEdit</a></span> <span class="operator">*</span>portLineEdit;
     <span class="type"><a href="qlabel.html">QLabel</a></span> <span class="operator">*</span>statusLabel;
     <span class="type"><a href="qpushbutton.html">QPushButton</a></span> <span class="operator">*</span>getFortuneButton;
     <span class="type"><a href="qpushbutton.html">QPushButton</a></span> <span class="operator">*</span>quitButton;
     <span class="type"><a href="qdialogbuttonbox.html">QDialogButtonBox</a></span> <span class="operator">*</span>buttonBox;

     <span class="type"><a href="qtcpsocket.html">QTcpSocket</a></span> <span class="operator">*</span>tcpSocket;
     <span class="type"><a href="qstring.html">QString</a></span> currentFortune;
     <span class="type"><a href="qtglobal.html#quint16-typedef">quint16</a></span> blockSize;

     <span class="type"><a href="qnetworksession.html">QNetworkSession</a></span> <span class="operator">*</span>networkSession;
 };</pre>
<p>Other than the widgets that make up the GUI, the data members include a <a href="qtcpsocket.html">QTcpSocket</a> pointer, a copy of the fortune text currently displayed, and the size of the packet we are currently reading (more on this later).</p>
<p>The socket is initialized in the Client constructor. We'll pass the main widget as parent, so that we won't have to worry about deleting the socket:</p>
<pre class="cpp"> Client<span class="operator">::</span>Client(<span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>parent)
 :   <span class="type"><a href="qdialog.html">QDialog</a></span>(parent)<span class="operator">,</span> networkSession(<span class="number">0</span>)
 {
     ...
     tcpSocket <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qtcpsocket.html">QTcpSocket</a></span>(<span class="keyword">this</span>);</pre>
<p>The only <a href="qtcpsocket.html">QTcpSocket</a> signals we need in this example are <a href="qiodevice.html#readyRead">QTcpSocket::readyRead</a>(), signifying that data has been received, and <a href="qabstractsocket.html#error">QTcpSocket::error</a>(), which we will use to catch any connection errors:</p>
<pre class="qml">     ...
     connect(tcpSocket<span class="operator">,</span> SIGNAL(readyRead())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(readFortune()));
     connect(tcpSocket<span class="operator">,</span> SIGNAL(error(<span class="type"><a href="qabstractsocket.html">QAbstractSocket</a></span><span class="operator">::</span>SocketError))<span class="operator">,</span>
     ...
 }</pre>
<p>Clicking the <b>Get Fortune</b> button will invoke the <tt>requestNewFortune()</tt> slot:</p>
<pre class="cpp"> <span class="type">void</span> Client<span class="operator">::</span>requestNewFortune()
 {
     getFortuneButton<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">false</span>);
     blockSize <span class="operator">=</span> <span class="number">0</span>;
     tcpSocket<span class="operator">-</span><span class="operator">&gt;</span>abort();
     tcpSocket<span class="operator">-</span><span class="operator">&gt;</span>connectToHost(hostLineEdit<span class="operator">-</span><span class="operator">&gt;</span>text()<span class="operator">,</span>
                              portLineEdit<span class="operator">-</span><span class="operator">&gt;</span>text()<span class="operator">.</span>toInt());
 }</pre>
<p>In this slot, we initialize <tt>blockSize</tt> to 0, preparing to read a new block of data. Because we allow the user to click <b>Get Fortune</b> before the previous connection finished closing, we start off by aborting the previous connection by calling <a href="qabstractsocket.html#abort">QTcpSocket::abort</a>(). (On an unconnected socket, this function does nothing.) We then proceed to connecting to the fortune server by calling <a href="qabstractsocket.html#connectToHost">QTcpSocket::connectToHost</a>(), passing the hostname and port from the user interface as arguments.</p>
<p>As a result of calling <a href="qabstractsocket.html#connectToHost">connectToHost()</a>, one of two things can happen:</p>
<ul>
<li><i>The connection is established.</i> In this case, the server will send us a fortune. <a href="qtcpsocket.html">QTcpSocket</a> will emit <a href="qiodevice.html#readyRead">readyRead()</a> every time it receives a block of data.</li>
<li><i>An error occurs.</i> We need to inform the user if the connection failed or was broken. In this case, <a href="qtcpsocket.html">QTcpSocket</a> will emit <a href="qabstractsocket.html#error">error()</a>, and <tt>Client::displayError()</tt> will be called.</li>
</ul>
<p>Let's go through the <a href="qabstractsocket.html#error">error()</a> case first:</p>
<pre class="cpp"> <span class="type">void</span> Client<span class="operator">::</span>displayError(<span class="type"><a href="qabstractsocket.html">QAbstractSocket</a></span><span class="operator">::</span>SocketError socketError)
 {
     <span class="keyword">switch</span> (socketError) {
     <span class="keyword">case</span> <span class="type"><a href="qabstractsocket.html">QAbstractSocket</a></span><span class="operator">::</span>RemoteHostClosedError:
         <span class="keyword">break</span>;
     <span class="keyword">case</span> <span class="type"><a href="qabstractsocket.html">QAbstractSocket</a></span><span class="operator">::</span>HostNotFoundError:
         <span class="type"><a href="qmessagebox.html">QMessageBox</a></span><span class="operator">::</span>information(<span class="keyword">this</span><span class="operator">,</span> tr(<span class="string">&quot;Fortune Client&quot;</span>)<span class="operator">,</span>
                                  tr(<span class="string">&quot;The host was not found. Please check the &quot;</span>
                                     <span class="string">&quot;host name and port settings.&quot;</span>));
         <span class="keyword">break</span>;
     <span class="keyword">case</span> <span class="type"><a href="qabstractsocket.html">QAbstractSocket</a></span><span class="operator">::</span>ConnectionRefusedError:
         <span class="type"><a href="qmessagebox.html">QMessageBox</a></span><span class="operator">::</span>information(<span class="keyword">this</span><span class="operator">,</span> tr(<span class="string">&quot;Fortune Client&quot;</span>)<span class="operator">,</span>
                                  tr(<span class="string">&quot;The connection was refused by the peer. &quot;</span>
                                     <span class="string">&quot;Make sure the fortune server is running, &quot;</span>
                                     <span class="string">&quot;and check that the host name and port &quot;</span>
                                     <span class="string">&quot;settings are correct.&quot;</span>));
         <span class="keyword">break</span>;
     <span class="keyword">default</span>:
         <span class="type"><a href="qmessagebox.html">QMessageBox</a></span><span class="operator">::</span>information(<span class="keyword">this</span><span class="operator">,</span> tr(<span class="string">&quot;Fortune Client&quot;</span>)<span class="operator">,</span>
                                  tr(<span class="string">&quot;The following error occurred: %1.&quot;</span>)
                                  <span class="operator">.</span>arg(tcpSocket<span class="operator">-</span><span class="operator">&gt;</span>errorString()));
     }

     getFortuneButton<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">true</span>);
 }</pre>
<p>We pop up all errors in a dialog using <a href="qmessagebox.html#information">QMessageBox::information</a>(). <a href="qabstractsocket.html#SocketError-enum">QTcpSocket::RemoteHostClosedError</a> is silently ignored, because the fortune server protocol ends with the server closing the connection.</p>
<p>Now for the <a href="qiodevice.html#readyRead">readyRead()</a> alternative. This signal is connected to <tt>Client::readFortune()</tt>:</p>
<pre class="cpp"> <span class="type">void</span> Client<span class="operator">::</span>readFortune()
 {
     <span class="type"><a href="qdatastream.html">QDataStream</a></span> in(tcpSocket);
     in<span class="operator">.</span>setVersion(<span class="type"><a href="qdatastream.html">QDataStream</a></span><span class="operator">::</span>Qt_4_0);

     <span class="keyword">if</span> (blockSize <span class="operator">=</span><span class="operator">=</span> <span class="number">0</span>) {
         <span class="keyword">if</span> (tcpSocket<span class="operator">-</span><span class="operator">&gt;</span>bytesAvailable() <span class="operator">&lt;</span> (<span class="type">int</span>)<span class="keyword">sizeof</span>(<span class="type"><a href="qtglobal.html#quint16-typedef">quint16</a></span>))
             <span class="keyword">return</span>;

         in <span class="operator">&gt;</span><span class="operator">&gt;</span> blockSize;
     }

     <span class="keyword">if</span> (tcpSocket<span class="operator">-</span><span class="operator">&gt;</span>bytesAvailable() <span class="operator">&lt;</span> blockSize)
         <span class="keyword">return</span>;</pre>
<p>The protocol is based on <a href="qdatastream.html">QDataStream</a>, so we start by creating a stream object, passing the socket to <a href="qdatastream.html">QDataStream</a>'s constructor. We then explicitly set the protocol version of the stream to <a href="qdatastream.html#Version-enum">QDataStream::Qt_4_0</a> to ensure that we're using the same version as the fortune server, no matter which version of Qt the client and server use.</p>
<p>Now, TCP is based on sending a stream of data, so we cannot expect to get the entire fortune in one go. Especially on a slow network, the data can be received in several small fragments. <a href="qtcpsocket.html">QTcpSocket</a> buffers up all incoming data and emits <a href="qiodevice.html#readyRead">readyRead()</a> for every new block that arrives, and it is our job to ensure that we have received all the data we need before we start parsing. The server's response starts with the size of the packet, so first we need to ensure that we can read the size, then we will wait until <a href="qtcpsocket.html">QTcpSocket</a> has received the full packet.</p>
<pre class="cpp">     <span class="type"><a href="qstring.html">QString</a></span> nextFortune;
     in <span class="operator">&gt;</span><span class="operator">&gt;</span> nextFortune;

     <span class="keyword">if</span> (nextFortune <span class="operator">=</span><span class="operator">=</span> currentFortune) {
         <span class="type"><a href="qtimer.html">QTimer</a></span><span class="operator">::</span>singleShot(<span class="number">0</span><span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(requestNewFortune()));
         <span class="keyword">return</span>;
     }

     currentFortune <span class="operator">=</span> nextFortune;
     statusLabel<span class="operator">-</span><span class="operator">&gt;</span>setText(currentFortune);
     getFortuneButton<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">true</span>);
 }</pre>
<p>We proceed by using <a href="qdatastream.html">QDataStream</a>'s streaming operator to read the fortune from the socket into a <a href="qstring.html">QString</a>. Once read, we can call <a href="qlabel.html#text-prop">QLabel::setText</a>() to display the fortune.</p>
</div>
<p><b>See also </b><a href="network-fortuneserver.html">Fortune Server Example</a> and <a href="network-blockingfortuneclient.html">Blocking Fortune Client Example</a>.</p>
<!-- @@@network/fortuneclient -->
      </div>
    </div>
    </div> 
    <div class="ft">
      <span></span>
    </div>
  </div> 
  <div class="footer">
    <p>
      <acronym title="Copyright">&copy;</acronym> 2015 The Qt Company Ltd.
      Documentation contributions included herein are the copyrights of
      their respective owners.</p>
    <br />
    <p>
      The documentation provided herein is licensed under the terms of the
      <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation
      License version 1.3</a> as published by the Free Software Foundation.</p>
    <p>
      Documentation sources may be obtained from <a href="http://www.qt-project.org">
      www.qt-project.org</a>.</p>
    <br />
    <p>
      Qt and respective logos are trademarks of The Qt Company Ltd 
      in Finland and/or other countries worldwide. All other trademarks are property
      of their respective owners. <a title="Privacy Policy"
      href="http://en.gitorious.org/privacy_policy/">Privacy Policy</a></p>
  </div>

  <script src="scripts/functions.js" type="text/javascript"></script>
</body>
</html>