summaryrefslogtreecommitdiffstats
path: root/examples/network/network-chat
diff options
context:
space:
mode:
Diffstat (limited to 'examples/network/network-chat')
-rw-r--r--examples/network/network-chat/chatdialog.cpp141
-rw-r--r--examples/network/network-chat/chatdialog.h69
-rw-r--r--examples/network/network-chat/chatdialog.ui79
-rw-r--r--examples/network/network-chat/client.cpp139
-rw-r--r--examples/network/network-chat/client.h82
-rw-r--r--examples/network/network-chat/connection.cpp275
-rw-r--r--examples/network/network-chat/connection.h107
-rw-r--r--examples/network/network-chat/main.cpp98
-rw-r--r--examples/network/network-chat/network-chat.pro26
-rw-r--r--examples/network/network-chat/peermanager.cpp172
-rw-r--r--examples/network/network-chat/peermanager.h84
-rw-r--r--examples/network/network-chat/server.cpp57
-rw-r--r--examples/network/network-chat/server.h62
13 files changed, 1391 insertions, 0 deletions
diff --git a/examples/network/network-chat/chatdialog.cpp b/examples/network/network-chat/chatdialog.cpp
new file mode 100644
index 0000000000..cdb29ea518
--- /dev/null
+++ b/examples/network/network-chat/chatdialog.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "chatdialog.h"
+
+ChatDialog::ChatDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ setupUi(this);
+
+ lineEdit->setFocusPolicy(Qt::StrongFocus);
+ textEdit->setFocusPolicy(Qt::NoFocus);
+ textEdit->setReadOnly(true);
+ listWidget->setFocusPolicy(Qt::NoFocus);
+
+ connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
+ connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
+ connect(&client, SIGNAL(newMessage(QString,QString)),
+ this, SLOT(appendMessage(QString,QString)));
+ connect(&client, SIGNAL(newParticipant(QString)),
+ this, SLOT(newParticipant(QString)));
+ connect(&client, SIGNAL(participantLeft(QString)),
+ this, SLOT(participantLeft(QString)));
+
+ myNickName = client.nickName();
+ newParticipant(myNickName);
+ tableFormat.setBorder(0);
+ QTimer::singleShot(10 * 1000, this, SLOT(showInformation()));
+}
+
+void ChatDialog::appendMessage(const QString &from, const QString &message)
+{
+ if (from.isEmpty() || message.isEmpty())
+ return;
+
+ QTextCursor cursor(textEdit->textCursor());
+ cursor.movePosition(QTextCursor::End);
+ QTextTable *table = cursor.insertTable(1, 2, tableFormat);
+ table->cellAt(0, 0).firstCursorPosition().insertText('<' + from + "> ");
+ table->cellAt(0, 1).firstCursorPosition().insertText(message);
+ QScrollBar *bar = textEdit->verticalScrollBar();
+ bar->setValue(bar->maximum());
+}
+
+void ChatDialog::returnPressed()
+{
+ QString text = lineEdit->text();
+ if (text.isEmpty())
+ return;
+
+ if (text.startsWith(QChar('/'))) {
+ QColor color = textEdit->textColor();
+ textEdit->setTextColor(Qt::red);
+ textEdit->append(tr("! Unknown command: %1")
+ .arg(text.left(text.indexOf(' '))));
+ textEdit->setTextColor(color);
+ } else {
+ client.sendMessage(text);
+ appendMessage(myNickName, text);
+ }
+
+ lineEdit->clear();
+}
+
+void ChatDialog::newParticipant(const QString &nick)
+{
+ if (nick.isEmpty())
+ return;
+
+ QColor color = textEdit->textColor();
+ textEdit->setTextColor(Qt::gray);
+ textEdit->append(tr("* %1 has joined").arg(nick));
+ textEdit->setTextColor(color);
+ listWidget->addItem(nick);
+}
+
+void ChatDialog::participantLeft(const QString &nick)
+{
+ if (nick.isEmpty())
+ return;
+
+ QList<QListWidgetItem *> items = listWidget->findItems(nick,
+ Qt::MatchExactly);
+ if (items.isEmpty())
+ return;
+
+ delete items.at(0);
+ QColor color = textEdit->textColor();
+ textEdit->setTextColor(Qt::gray);
+ textEdit->append(tr("* %1 has left").arg(nick));
+ textEdit->setTextColor(color);
+}
+
+void ChatDialog::showInformation()
+{
+ if (listWidget->count() == 1) {
+ QMessageBox::information(this, tr("Chat"),
+ tr("Launch several instances of this "
+ "program on your local network and "
+ "start chatting!"));
+ }
+}
diff --git a/examples/network/network-chat/chatdialog.h b/examples/network/network-chat/chatdialog.h
new file mode 100644
index 0000000000..258206a905
--- /dev/null
+++ b/examples/network/network-chat/chatdialog.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CHATDIALOG_H
+#define CHATDIALOG_H
+
+#include "ui_chatdialog.h"
+#include "client.h"
+
+class ChatDialog : public QDialog, private Ui::ChatDialog
+{
+ Q_OBJECT
+
+public:
+ ChatDialog(QWidget *parent = 0);
+
+public slots:
+ void appendMessage(const QString &from, const QString &message);
+
+private slots:
+ void returnPressed();
+ void newParticipant(const QString &nick);
+ void participantLeft(const QString &nick);
+ void showInformation();
+
+private:
+ Client client;
+ QString myNickName;
+ QTextTableFormat tableFormat;
+};
+
+#endif
diff --git a/examples/network/network-chat/chatdialog.ui b/examples/network/network-chat/chatdialog.ui
new file mode 100644
index 0000000000..c85e0d0f55
--- /dev/null
+++ b/examples/network/network-chat/chatdialog.ui
@@ -0,0 +1,79 @@
+<ui version="4.0" >
+ <class>ChatDialog</class>
+ <widget class="QDialog" name="ChatDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>513</width>
+ <height>349</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Chat</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QTextEdit" name="textEdit" >
+ <property name="focusPolicy" >
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listWidget" >
+ <property name="maximumSize" >
+ <size>
+ <width>180</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="focusPolicy" >
+ <enum>Qt::NoFocus</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Message:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEdit" />
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/network/network-chat/client.cpp b/examples/network/network-chat/client.cpp
new file mode 100644
index 0000000000..d9f594e8ac
--- /dev/null
+++ b/examples/network/network-chat/client.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtNetwork>
+
+#include "client.h"
+#include "connection.h"
+#include "peermanager.h"
+
+Client::Client()
+{
+ peerManager = new PeerManager(this);
+ peerManager->setServerPort(server.serverPort());
+ peerManager->startBroadcasting();
+
+ QObject::connect(peerManager, SIGNAL(newConnection(Connection*)),
+ this, SLOT(newConnection(Connection*)));
+ QObject::connect(&server, SIGNAL(newConnection(Connection*)),
+ this, SLOT(newConnection(Connection*)));
+}
+
+void Client::sendMessage(const QString &message)
+{
+ if (message.isEmpty())
+ return;
+
+ QList<Connection *> connections = peers.values();
+ foreach (Connection *connection, connections)
+ connection->sendMessage(message);
+}
+
+QString Client::nickName() const
+{
+ return QString(peerManager->userName()) + '@' + QHostInfo::localHostName()
+ + ':' + QString::number(server.serverPort());
+}
+
+bool Client::hasConnection(const QHostAddress &senderIp, int senderPort) const
+{
+ if (senderPort == -1)
+ return peers.contains(senderIp);
+
+ if (!peers.contains(senderIp))
+ return false;
+
+ QList<Connection *> connections = peers.values(senderIp);
+ foreach (Connection *connection, connections) {
+ if (connection->peerPort() == senderPort)
+ return true;
+ }
+
+ return false;
+}
+
+void Client::newConnection(Connection *connection)
+{
+ connection->setGreetingMessage(peerManager->userName());
+
+ connect(connection, SIGNAL(error(QAbstractSocket::SocketError)),
+ this, SLOT(connectionError(QAbstractSocket::SocketError)));
+ connect(connection, SIGNAL(disconnected()), this, SLOT(disconnected()));
+ connect(connection, SIGNAL(readyForUse()), this, SLOT(readyForUse()));
+}
+
+void Client::readyForUse()
+{
+ Connection *connection = qobject_cast<Connection *>(sender());
+ if (!connection || hasConnection(connection->peerAddress(),
+ connection->peerPort()))
+ return;
+
+ connect(connection, SIGNAL(newMessage(QString,QString)),
+ this, SIGNAL(newMessage(QString,QString)));
+
+ peers.insert(connection->peerAddress(), connection);
+ QString nick = connection->name();
+ if (!nick.isEmpty())
+ emit newParticipant(nick);
+}
+
+void Client::disconnected()
+{
+ if (Connection *connection = qobject_cast<Connection *>(sender()))
+ removeConnection(connection);
+}
+
+void Client::connectionError(QAbstractSocket::SocketError /* socketError */)
+{
+ if (Connection *connection = qobject_cast<Connection *>(sender()))
+ removeConnection(connection);
+}
+
+void Client::removeConnection(Connection *connection)
+{
+ if (peers.contains(connection->peerAddress())) {
+ peers.remove(connection->peerAddress());
+ QString nick = connection->name();
+ if (!nick.isEmpty())
+ emit participantLeft(nick);
+ }
+ connection->deleteLater();
+}
diff --git a/examples/network/network-chat/client.h b/examples/network/network-chat/client.h
new file mode 100644
index 0000000000..317fef36a8
--- /dev/null
+++ b/examples/network/network-chat/client.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CLIENT_H
+#define CLIENT_H
+
+#include <QAbstractSocket>
+#include <QHash>
+#include <QHostAddress>
+
+#include "server.h"
+
+class PeerManager;
+
+class Client : public QObject
+{
+ Q_OBJECT
+
+public:
+ Client();
+
+ void sendMessage(const QString &message);
+ QString nickName() const;
+ bool hasConnection(const QHostAddress &senderIp, int senderPort = -1) const;
+
+signals:
+ void newMessage(const QString &from, const QString &message);
+ void newParticipant(const QString &nick);
+ void participantLeft(const QString &nick);
+
+private slots:
+ void newConnection(Connection *connection);
+ void connectionError(QAbstractSocket::SocketError socketError);
+ void disconnected();
+ void readyForUse();
+
+private:
+ void removeConnection(Connection *connection);
+
+ PeerManager *peerManager;
+ Server server;
+ QMultiHash<QHostAddress, Connection *> peers;
+};
+
+#endif
diff --git a/examples/network/network-chat/connection.cpp b/examples/network/network-chat/connection.cpp
new file mode 100644
index 0000000000..9171d1fc5f
--- /dev/null
+++ b/examples/network/network-chat/connection.cpp
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "connection.h"
+
+#include <QtNetwork>
+
+static const int TransferTimeout = 30 * 1000;
+static const int PongTimeout = 60 * 1000;
+static const int PingInterval = 5 * 1000;
+static const char SeparatorToken = ' ';
+
+Connection::Connection(QObject *parent)
+ : QTcpSocket(parent)
+{
+ greetingMessage = tr("undefined");
+ username = tr("unknown");
+ state = WaitingForGreeting;
+ currentDataType = Undefined;
+ numBytesForCurrentDataType = -1;
+ transferTimerId = 0;
+ isGreetingMessageSent = false;
+ pingTimer.setInterval(PingInterval);
+
+ QObject::connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead()));
+ QObject::connect(this, SIGNAL(disconnected()), &pingTimer, SLOT(stop()));
+ QObject::connect(&pingTimer, SIGNAL(timeout()), this, SLOT(sendPing()));
+ QObject::connect(this, SIGNAL(connected()),
+ this, SLOT(sendGreetingMessage()));
+}
+
+QString Connection::name() const
+{
+ return username;
+}
+
+void Connection::setGreetingMessage(const QString &message)
+{
+ greetingMessage = message;
+}
+
+bool Connection::sendMessage(const QString &message)
+{
+ if (message.isEmpty())
+ return false;
+
+ QByteArray msg = message.toUtf8();
+ QByteArray data = "MESSAGE " + QByteArray::number(msg.size()) + ' ' + msg;
+ return write(data) == data.size();
+}
+
+void Connection::timerEvent(QTimerEvent *timerEvent)
+{
+ if (timerEvent->timerId() == transferTimerId) {
+ abort();
+ killTimer(transferTimerId);
+ transferTimerId = 0;
+ }
+}
+
+void Connection::processReadyRead()
+{
+ if (state == WaitingForGreeting) {
+ if (!readProtocolHeader())
+ return;
+ if (currentDataType != Greeting) {
+ abort();
+ return;
+ }
+ state = ReadingGreeting;
+ }
+
+ if (state == ReadingGreeting) {
+ if (!hasEnoughData())
+ return;
+
+ buffer = read(numBytesForCurrentDataType);
+ if (buffer.size() != numBytesForCurrentDataType) {
+ abort();
+ return;
+ }
+
+ username = QString(buffer) + '@' + peerAddress().toString() + ':'
+ + QString::number(peerPort());
+ currentDataType = Undefined;
+ numBytesForCurrentDataType = 0;
+ buffer.clear();
+
+ if (!isValid()) {
+ abort();
+ return;
+ }
+
+ if (!isGreetingMessageSent)
+ sendGreetingMessage();
+
+ pingTimer.start();
+ pongTime.start();
+ state = ReadyForUse;
+ emit readyForUse();
+ }
+
+ do {
+ if (currentDataType == Undefined) {
+ if (!readProtocolHeader())
+ return;
+ }
+ if (!hasEnoughData())
+ return;
+ processData();
+ } while (bytesAvailable() > 0);
+}
+
+void Connection::sendPing()
+{
+ if (pongTime.elapsed() > PongTimeout) {
+ abort();
+ return;
+ }
+
+ write("PING 1 p");
+}
+
+void Connection::sendGreetingMessage()
+{
+ QByteArray greeting = greetingMessage.toUtf8();
+ QByteArray data = "GREETING " + QByteArray::number(greeting.size()) + ' ' + greeting;
+ if (write(data) == data.size())
+ isGreetingMessageSent = true;
+}
+
+int Connection::readDataIntoBuffer(int maxSize)
+{
+ if (maxSize > MaxBufferSize)
+ return 0;
+
+ int numBytesBeforeRead = buffer.size();
+ if (numBytesBeforeRead == MaxBufferSize) {
+ abort();
+ return 0;
+ }
+
+ while (bytesAvailable() > 0 && buffer.size() < maxSize) {
+ buffer.append(read(1));
+ if (buffer.endsWith(SeparatorToken))
+ break;
+ }
+ return buffer.size() - numBytesBeforeRead;
+}
+
+int Connection::dataLengthForCurrentDataType()
+{
+ if (bytesAvailable() <= 0 || readDataIntoBuffer() <= 0
+ || !buffer.endsWith(SeparatorToken))
+ return 0;
+
+ buffer.chop(1);
+ int number = buffer.toInt();
+ buffer.clear();
+ return number;
+}
+
+bool Connection::readProtocolHeader()
+{
+ if (transferTimerId) {
+ killTimer(transferTimerId);
+ transferTimerId = 0;
+ }
+
+ if (readDataIntoBuffer() <= 0) {
+ transferTimerId = startTimer(TransferTimeout);
+ return false;
+ }
+
+ if (buffer == "PING ") {
+ currentDataType = Ping;
+ } else if (buffer == "PONG ") {
+ currentDataType = Pong;
+ } else if (buffer == "MESSAGE ") {
+ currentDataType = PlainText;
+ } else if (buffer == "GREETING ") {
+ currentDataType = Greeting;
+ } else {
+ currentDataType = Undefined;
+ abort();
+ return false;
+ }
+
+ buffer.clear();
+ numBytesForCurrentDataType = dataLengthForCurrentDataType();
+ return true;
+}
+
+bool Connection::hasEnoughData()
+{
+ if (transferTimerId) {
+ QObject::killTimer(transferTimerId);
+ transferTimerId = 0;
+ }
+
+ if (numBytesForCurrentDataType <= 0)
+ numBytesForCurrentDataType = dataLengthForCurrentDataType();
+
+ if (bytesAvailable() < numBytesForCurrentDataType
+ || numBytesForCurrentDataType <= 0) {
+ transferTimerId = startTimer(TransferTimeout);
+ return false;
+ }
+
+ return true;
+}
+
+void Connection::processData()
+{
+ buffer = read(numBytesForCurrentDataType);
+ if (buffer.size() != numBytesForCurrentDataType) {
+ abort();
+ return;
+ }
+
+ switch (currentDataType) {
+ case PlainText:
+ emit newMessage(username, QString::fromUtf8(buffer));
+ break;
+ case Ping:
+ write("PONG 1 p");
+ break;
+ case Pong:
+ pongTime.restart();
+ break;
+ default:
+ break;
+ }
+
+ currentDataType = Undefined;
+ numBytesForCurrentDataType = 0;
+ buffer.clear();
+}
diff --git a/examples/network/network-chat/connection.h b/examples/network/network-chat/connection.h
new file mode 100644
index 0000000000..5db5cc59e8
--- /dev/null
+++ b/examples/network/network-chat/connection.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CONNECTION_H
+#define CONNECTION_H
+
+#include <QHostAddress>
+#include <QString>
+#include <QTcpSocket>
+#include <QTime>
+#include <QTimer>
+
+static const int MaxBufferSize = 1024000;
+
+class Connection : public QTcpSocket
+{
+ Q_OBJECT
+
+public:
+ enum ConnectionState {
+ WaitingForGreeting,
+ ReadingGreeting,
+ ReadyForUse
+ };
+ enum DataType {
+ PlainText,
+ Ping,
+ Pong,
+ Greeting,
+ Undefined
+ };
+
+ Connection(QObject *parent = 0);
+
+ QString name() const;
+ void setGreetingMessage(const QString &message);
+ bool sendMessage(const QString &message);
+
+signals:
+ void readyForUse();
+ void newMessage(const QString &from, const QString &message);
+
+protected:
+ void timerEvent(QTimerEvent *timerEvent);
+
+private slots:
+ void processReadyRead();
+ void sendPing();
+ void sendGreetingMessage();
+
+private:
+ int readDataIntoBuffer(int maxSize = MaxBufferSize);
+ int dataLengthForCurrentDataType();
+ bool readProtocolHeader();
+ bool hasEnoughData();
+ void processData();
+
+ QString greetingMessage;
+ QString username;
+ QTimer pingTimer;
+ QTime pongTime;
+ QByteArray buffer;
+ ConnectionState state;
+ DataType currentDataType;
+ int numBytesForCurrentDataType;
+ int transferTimerId;
+ bool isGreetingMessageSent;
+};
+
+#endif
diff --git a/examples/network/network-chat/main.cpp b/examples/network/network-chat/main.cpp
new file mode 100644
index 0000000000..a126172b74
--- /dev/null
+++ b/examples/network/network-chat/main.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+#include "chatdialog.h"
+
+#include <QtCore/QSettings>
+#include <QtNetwork/QNetworkConfigurationManager>
+#include <QtNetwork/QNetworkSession>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ QNetworkConfigurationManager manager;
+ if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
+ // Get saved network configuration
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("QtNetwork"));
+ const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
+ settings.endGroup();
+
+ // If the saved network configuration is not currently discovered use the system default
+ QNetworkConfiguration config = manager.configurationFromIdentifier(id);
+ if ((config.state() & QNetworkConfiguration::Discovered) !=
+ QNetworkConfiguration::Discovered) {
+ config = manager.defaultConfiguration();
+ }
+
+ QNetworkSession *networkSession = new QNetworkSession(config, &app);
+ networkSession->open();
+ networkSession->waitForOpened();
+
+ if (networkSession->isOpen()) {
+ // Save the used configuration
+ QNetworkConfiguration config = networkSession->configuration();
+ QString id;
+ if (config.type() == QNetworkConfiguration::UserChoice) {
+ id = networkSession->sessionProperty(
+ QLatin1String("UserChoiceConfiguration")).toString();
+ } else {
+ id = config.identifier();
+ }
+
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("QtNetwork"));
+ settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
+ settings.endGroup();
+ }
+ }
+
+ ChatDialog dialog;
+#ifdef Q_OS_SYMBIAN
+ // Make application better looking and more usable on small screen
+ dialog.showMaximized();
+#else
+ dialog.show();
+#endif
+ return app.exec();
+}
diff --git a/examples/network/network-chat/network-chat.pro b/examples/network/network-chat/network-chat.pro
new file mode 100644
index 0000000000..11f2d2ef30
--- /dev/null
+++ b/examples/network/network-chat/network-chat.pro
@@ -0,0 +1,26 @@
+HEADERS = chatdialog.h \
+ client.h \
+ connection.h \
+ peermanager.h \
+ server.h
+SOURCES = chatdialog.cpp \
+ client.cpp \
+ connection.cpp \
+ main.cpp \
+ peermanager.cpp \
+ server.cpp
+FORMS = chatdialog.ui
+QT += network
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/network/network-chat
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS network-chat.pro *.chat
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/network/network-chat
+INSTALLS += target sources
+
+symbian {
+ include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
+ LIBS += -lcharconv
+ TARGET.CAPABILITY = "NetworkServices ReadUserData WriteUserData"
+ TARGET.EPOCHEAPSIZE = 0x20000 0x2000000
+}
diff --git a/examples/network/network-chat/peermanager.cpp b/examples/network/network-chat/peermanager.cpp
new file mode 100644
index 0000000000..0e5bd1724e
--- /dev/null
+++ b/examples/network/network-chat/peermanager.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtNetwork>
+
+#include "client.h"
+#include "connection.h"
+#include "peermanager.h"
+
+static const qint32 BroadcastInterval = 2000;
+static const unsigned broadcastPort = 45000;
+
+PeerManager::PeerManager(Client *client)
+ : QObject(client)
+{
+ this->client = client;
+
+ QStringList envVariables;
+ envVariables << "USERNAME.*" << "USER.*" << "USERDOMAIN.*"
+ << "HOSTNAME.*" << "DOMAINNAME.*";
+
+ QStringList environment = QProcess::systemEnvironment();
+ foreach (QString string, envVariables) {
+ int index = environment.indexOf(QRegExp(string));
+ if (index != -1) {
+ QStringList stringList = environment.at(index).split('=');
+ if (stringList.size() == 2) {
+ username = stringList.at(1).toUtf8();
+ break;
+ }
+ }
+ }
+
+ if (username.isEmpty())
+#ifndef Q_OS_SYMBIAN
+ username = "unknown";
+#else
+ username = "QtS60";
+#endif
+
+ updateAddresses();
+ serverPort = 0;
+
+ broadcastSocket.bind(QHostAddress::Any, broadcastPort, QUdpSocket::ShareAddress
+ | QUdpSocket::ReuseAddressHint);
+ connect(&broadcastSocket, SIGNAL(readyRead()),
+ this, SLOT(readBroadcastDatagram()));
+
+ broadcastTimer.setInterval(BroadcastInterval);
+ connect(&broadcastTimer, SIGNAL(timeout()),
+ this, SLOT(sendBroadcastDatagram()));
+}
+
+void PeerManager::setServerPort(int port)
+{
+ serverPort = port;
+}
+
+QByteArray PeerManager::userName() const
+{
+ return username;
+}
+
+void PeerManager::startBroadcasting()
+{
+ broadcastTimer.start();
+}
+
+bool PeerManager::isLocalHostAddress(const QHostAddress &address)
+{
+ foreach (QHostAddress localAddress, ipAddresses) {
+ if (address == localAddress)
+ return true;
+ }
+ return false;
+}
+
+void PeerManager::sendBroadcastDatagram()
+{
+ QByteArray datagram(username);
+ datagram.append('@');
+ datagram.append(QByteArray::number(serverPort));
+
+ bool validBroadcastAddresses = true;
+ foreach (QHostAddress address, broadcastAddresses) {
+ if (broadcastSocket.writeDatagram(datagram, address,
+ broadcastPort) == -1)
+ validBroadcastAddresses = false;
+ }
+
+ if (!validBroadcastAddresses)
+ updateAddresses();
+}
+
+void PeerManager::readBroadcastDatagram()
+{
+ while (broadcastSocket.hasPendingDatagrams()) {
+ QHostAddress senderIp;
+ quint16 senderPort;
+ QByteArray datagram;
+ datagram.resize(broadcastSocket.pendingDatagramSize());
+ if (broadcastSocket.readDatagram(datagram.data(), datagram.size(),
+ &senderIp, &senderPort) == -1)
+ continue;
+
+ QList<QByteArray> list = datagram.split('@');
+ if (list.size() != 2)
+ continue;
+
+ int senderServerPort = list.at(1).toInt();
+ if (isLocalHostAddress(senderIp) && senderServerPort == serverPort)
+ continue;
+
+ if (!client->hasConnection(senderIp)) {
+ Connection *connection = new Connection(this);
+ emit newConnection(connection);
+ connection->connectToHost(senderIp, senderServerPort);
+ }
+ }
+}
+
+void PeerManager::updateAddresses()
+{
+ broadcastAddresses.clear();
+ ipAddresses.clear();
+ foreach (QNetworkInterface interface, QNetworkInterface::allInterfaces()) {
+ foreach (QNetworkAddressEntry entry, interface.addressEntries()) {
+ QHostAddress broadcastAddress = entry.broadcast();
+ if (broadcastAddress != QHostAddress::Null && entry.ip() != QHostAddress::LocalHost) {
+ broadcastAddresses << broadcastAddress;
+ ipAddresses << entry.ip();
+ }
+ }
+ }
+}
diff --git a/examples/network/network-chat/peermanager.h b/examples/network/network-chat/peermanager.h
new file mode 100644
index 0000000000..a061bbbb53
--- /dev/null
+++ b/examples/network/network-chat/peermanager.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PEERMANAGER_H
+#define PEERMANAGER_H
+
+#include <QByteArray>
+#include <QList>
+#include <QObject>
+#include <QTimer>
+#include <QUdpSocket>
+
+class Client;
+class Connection;
+
+class PeerManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ PeerManager(Client *client);
+
+ void setServerPort(int port);
+ QByteArray userName() const;
+ void startBroadcasting();
+ bool isLocalHostAddress(const QHostAddress &address);
+
+signals:
+ void newConnection(Connection *connection);
+
+private slots:
+ void sendBroadcastDatagram();
+ void readBroadcastDatagram();
+
+private:
+ void updateAddresses();
+
+ Client *client;
+ QList<QHostAddress> broadcastAddresses;
+ QList<QHostAddress> ipAddresses;
+ QUdpSocket broadcastSocket;
+ QTimer broadcastTimer;
+ QByteArray username;
+ int serverPort;
+};
+
+#endif
diff --git a/examples/network/network-chat/server.cpp b/examples/network/network-chat/server.cpp
new file mode 100644
index 0000000000..4a3a28298a
--- /dev/null
+++ b/examples/network/network-chat/server.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtNetwork>
+
+#include "connection.h"
+#include "server.h"
+
+Server::Server(QObject *parent)
+ : QTcpServer(parent)
+{
+ listen(QHostAddress::Any);
+}
+
+void Server::incomingConnection(int socketDescriptor)
+{
+ Connection *connection = new Connection(this);
+ connection->setSocketDescriptor(socketDescriptor);
+ emit newConnection(connection);
+}
diff --git a/examples/network/network-chat/server.h b/examples/network/network-chat/server.h
new file mode 100644
index 0000000000..0d88c873da
--- /dev/null
+++ b/examples/network/network-chat/server.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SERVER_H
+#define SERVER_H
+
+#include <QTcpServer>
+
+class Connection;
+
+class Server : public QTcpServer
+{
+ Q_OBJECT
+
+public:
+ Server(QObject *parent = 0);
+
+signals:
+ void newConnection(Connection *connection);
+
+protected:
+ void incomingConnection(int socketDescriptor);
+};
+
+#endif