Sophie

Sophie

distrib > Mandriva > current > i586 > media > main-updates > by-pkgid > 8e6051afcdb111a0317a58fb64c2abf5 > files > 2933

qt4-doc-4.6.3-0.2mdv2010.2.i586.rpm

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- fortuneserver.qdoc -->
<head>
  <title>Qt 4.6: Fortune Server Example</title>
  <link href="classic.css" rel="stylesheet" type="text/css" />
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td align="left" valign="top" width="32"><a href="http://qt.nokia.com/"><img src="images/qt-logo.png" align="left" border="0" /></a></td>
<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a>&nbsp;&middot; <a href="classes.html"><font color="#004faf">All&nbsp;Classes</font></a>&nbsp;&middot; <a href="functions.html"><font color="#004faf">All&nbsp;Functions</font></a>&nbsp;&middot; <a href="overviews.html"><font color="#004faf">Overviews</font></a></td></tr></table><h1 class="title">Fortune Server Example<br /><span class="subtitle"></span>
</h1>
<p>Files:</p>
<ul>
<li><a href="network-fortuneserver-server-cpp.html">network/fortuneserver/server.cpp</a></li>
<li><a href="network-fortuneserver-server-h.html">network/fortuneserver/server.h</a></li>
<li><a href="network-fortuneserver-main-cpp.html">network/fortuneserver/main.cpp</a></li>
<li><a href="network-fortuneserver-fortuneserver-pro.html">network/fortuneserver/fortuneserver.pro</a></li>
</ul>
<p>The Fortune Server example shows how to create a server for a simple network service. It is intended to be run alongside the <a href="network-fortuneclient.html">Fortune Client</a> example or the <a href="network-blockingfortuneclient.html">Blocking Fortune Client</a> example.</p>
<p align="center"><img src="images/fortuneserver-example.png" alt="Screenshot of the Fortune Server example" /></p><p>This example uses <a href="qtcpserver.html">QTcpServer</a> to accept incoming TCP connections, and a simple <a href="qdatastream.html">QDataStream</a> based data transfer protocol to write a fortune to the connecting client (from the <a href="network-fortuneclient.html">Fortune Client</a> example), before closing the connection.</p>
<pre> class Server : public QDialog
 {
     Q_OBJECT

 public:
     Server(QWidget *parent = 0);

 private slots:
     void sendFortune();

 private:
     QLabel *statusLabel;
     QPushButton *quitButton;
     QTcpServer *tcpServer;
     QStringList fortunes;
 };</pre>
<p>The server is implemented using a simple class with only one slot, for handling incoming connections.</p>
<pre>     tcpServer = new QTcpServer(this);
     if (!tcpServer-&gt;listen()) {
         QMessageBox::critical(this, tr(&quot;Fortune Server&quot;),
                               tr(&quot;Unable to start the server: %1.&quot;)
                               .arg(tcpServer-&gt;errorString()));
         close();
         return;
     }
     QString ipAddress;
     QList&lt;QHostAddress&gt; ipAddressesList = QNetworkInterface::allAddresses();
     <span class="comment">// use the first non-localhost IPv4 address</span>
     for (int i = 0; i &lt; ipAddressesList.size(); ++i) {
         if (ipAddressesList.at(i) != QHostAddress::LocalHost &amp;&amp;
             ipAddressesList.at(i).toIPv4Address()) {
             ipAddress = ipAddressesList.at(i).toString();
             break;
         }
     }
     <span class="comment">// if we did not find one, use IPv4 localhost</span>
     if (ipAddress.isEmpty())
         ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
     statusLabel-&gt;setText(tr(&quot;The server is running on\n\nIP: %1\nport: %2\n\n&quot;
                             &quot;Run the Fortune Client example now.&quot;)
                          .arg(ipAddress).arg(tcpServer-&gt;serverPort()));</pre>
<p>In its constructor, our Server object calls <a href="qtcpserver.html#listen">QTcpServer::listen</a>() to set up a <a href="qtcpserver.html">QTcpServer</a> to listen on all addresses, on an arbitrary port. In then displays the port <a href="qtcpserver.html">QTcpServer</a> picked in a label, so that user knows which port the fortune client should connect to.</p>
<pre>     fortunes &lt;&lt; tr(&quot;You've been leading a dog's life. Stay off the furniture.&quot;)
              &lt;&lt; tr(&quot;You've got to think about tomorrow.&quot;)
              &lt;&lt; tr(&quot;You will be surprised by a loud noise.&quot;)
              &lt;&lt; tr(&quot;You will feel hungry again in another hour.&quot;)
              &lt;&lt; tr(&quot;You might have mail.&quot;)
              &lt;&lt; tr(&quot;You cannot kill time without injuring eternity.&quot;)
              &lt;&lt; tr(&quot;Computers are not intelligent. They only think they are.&quot;);</pre>
<p>Our server generates a list of random fortunes that is can send to connecting clients.</p>
<pre>     connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendFortune()));</pre>
<p>When a client connects to our server, <a href="qtcpserver.html">QTcpServer</a> will emit <a href="qtcpserver.html#newConnection">QTcpServer::newConnection</a>(). In turn, this will invoke our sendFortune() slot:</p>
<pre> void Server::sendFortune()
 {
     QByteArray block;
     QDataStream out(&amp;block, QIODevice::WriteOnly);
     out.setVersion(QDataStream::Qt_4_0);</pre>
<p>The purpose of this slot is to select a random line from our list of fortunes, encode it into a <a href="qbytearray.html">QByteArray</a> using <a href="qdatastream.html">QDataStream</a>, and then write it to the connecting socket. This is a common way to transfer binary data using <a href="qtcpsocket.html">QTcpSocket</a>. First we create a <a href="qbytearray.html">QByteArray</a> and a <a href="qdatastream.html">QDataStream</a> object, passing the bytearray to <a href="qdatastream.html">QDataStream</a>'s constructor. We then explicitly set the protocol version of <a href="qdatastream.html">QDataStream</a> to <a href="qdatastream.html#Version-enum">QDataStream::Qt_4_0</a> to ensure that we can communicate with clients from future versions of Qt. (See <a href="qdatastream.html#setVersion">QDataStream::setVersion</a>().)</p>
<pre>     out &lt;&lt; (quint16)0;
     out &lt;&lt; fortunes.at(qrand() % fortunes.size());
     out.device()-&gt;seek(0);
     out &lt;&lt; (quint16)(block.size() - sizeof(quint16));</pre>
<p>At the start of our <a href="qbytearray.html">QByteArray</a>, we reserve space for a 16 bit integer that will contain the total size of the data block we are sending. We continue by streaming in a random fortune. Then we seek back to the beginning of the <a href="qbytearray.html">QByteArray</a>, and overwrite the reserved 16 bit integer value with the total size of the array. By doing this, we provide a way for clients to verify how much data they can expect before reading the whole packet.</p>
<pre>     QTcpSocket *clientConnection = tcpServer-&gt;nextPendingConnection();
     connect(clientConnection, SIGNAL(disconnected()),
             clientConnection, SLOT(deleteLater()));</pre>
<p>We then call QTcpServer::newPendingConnection(), which returns the <a href="qtcpsocket.html">QTcpSocket</a> representing the server side of the connection. By connecting <a href="qabstractsocket.html#disconnected">QTcpSocket::disconnected</a>() to <a href="qobject.html#deleteLater">QObject::deleteLater</a>(), we ensure that the socket will be deleted after disconnecting.</p>
<pre>     clientConnection-&gt;write(block);
     clientConnection-&gt;disconnectFromHost();
 }</pre>
<p>The encoded fortune is written using <a href="qiodevice.html#write">QTcpSocket::write</a>(), and we finally call <a href="qabstractsocket.html#disconnectFromHost">QTcpSocket::disconnectFromHost</a>(), which will close the connection after <a href="qtcpsocket.html">QTcpSocket</a> has finished writing the fortune to the network. Because <a href="qtcpsocket.html">QTcpSocket</a> works asynchronously, the data will be written after this function returns, and control goes back to Qt's event loop. The socket will then close, which in turn will cause <a href="qobject.html#deleteLater">QObject::deleteLater</a>() to delete it.</p>
<p>See also <a href="network-fortuneclient.html">Fortune Client Example</a> and <a href="network-threadedfortuneserver.html">Threaded Fortune Server Example</a>.</p>
<p /><address><hr /><div align="center">
<table width="100%" cellspacing="0" border="0"><tr class="address">
<td width="40%" align="left">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies)</td>
<td width="20%" align="center"><a href="trademarks.html">Trademarks</a></td>
<td width="40%" align="right"><div align="right">Qt 4.6.3</div></td>
</tr></table></div></address></body>
</html>