Network Chat Example▲
Sélectionnez
/**
**************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, 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 The Qt Company Ltd 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-&
gt;setServerPort(server.serverPort());
peerManager-&
gt;startBroadcasting();
QObject::
connect(peerManager, SIGNAL(newConnection(Connection*
)),
this
, SLOT(newConnection(Connection*
)));
QObject::
connect(&
amp;server, SIGNAL(newConnection(Connection*
)),
this
, SLOT(newConnection(Connection*
)));
}
void
Client::
sendMessage(const
QString &
amp;message)
{
if
(message.isEmpty())
return
;
QList&
lt;Connection *&
gt; connections =
peers.values();
foreach (Connection *
connection, connections)
connection-&
gt;sendMessage(message);
}
QString Client::
nickName() const
{
return
peerManager-&
gt;userName() +
'@'
+
QHostInfo::
localHostName()
+
':'
+
QString::
number(server.serverPort());
}
bool
Client::
hasConnection(const
QHostAddress &
amp;senderIp, int
senderPort) const
{
if
(senderPort ==
-
1
)
return
peers.contains(senderIp);
if
(!
peers.contains(senderIp))
return
false
;
QList&
lt;Connection *&
gt; connections =
peers.values(senderIp);
foreach (Connection *
connection, connections) {
if
(connection-&
gt;peerPort() ==
senderPort)
return
true
;
}
return
false
;
}
void
Client::
newConnection(Connection *
connection)
{
connection-&
gt;setGreetingMessage(peerManager-&
gt;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&
lt;Connection *&
gt;(sender());
if
(!
connection ||
hasConnection(connection-&
gt;peerAddress(),
connection-&
gt;peerPort()))
return
;
connect(connection, SIGNAL(newMessage(QString,QString)),
this
, SIGNAL(newMessage(QString,QString)));
peers.insert(connection-&
gt;peerAddress(), connection);
QString nick =
connection-&
gt;name();
if
(!
nick.isEmpty())
emit newParticipant(nick);
}
void
Client::
disconnected()
{
if
(Connection *
connection =
qobject_cast&
lt;Connection *&
gt;(sender()))
removeConnection(connection);
}
void
Client::
connectionError(QAbstractSocket::
SocketError /* socketError */
)
{
if
(Connection *
connection =
qobject_cast&
lt;Connection *&
gt;(sender()))
removeConnection(connection);
}
void
Client::
removeConnection(Connection *
connection)
{
if
(peers.contains(connection-&
gt;peerAddress())) {
peers.remove(connection-&
gt;peerAddress());
QString nick =
connection-&
gt;name();
if
(!
nick.isEmpty())
emit participantLeft(nick);
}
connection-&
gt;deleteLater();
}