cooler123
27th September 2007, 08:17
I want to show the connected client in tree. I am able to create the tree but i having problem to remove it when a client is disconnected.
Header file:
#ifndef SERVER_H
#define SERVER_H
#include <QDialog>
#include <QList>
#include <QHash>
class QLabel;
class QPushButton;
class QTcpSocket;
class QTextEdit;
class QTcpServer;
class QLineEdit;
class QBuffer;
class QStringList;
class QTreeWidget;
class QTreeWidgetItem;
class Server : public QDialog
{
Q_OBJECT
public:
Server(QWidget *parent = 0);
~Server();
protected:
void sendToClients(const QByteArray& line);
private slots:
//void sendMessage();
void slotStartButtonEnable();
void slotStartClicked();
void slotStopClicked();
void slotNewClient();
void slotClientDisconnected();
void slotSocketRead();
private:
QList<QTcpSocket*> connections;
QHash<QTcpSocket*, QBuffer*> buffers;
//QHash<QTcpSocket*, int> itemList;
QList<QTreeWidgetItem *> liClients;
QTreeWidget *twClientConnected;
QStringList slTreeLabel;
QLineEdit *lePort;
QLabel *lblPort;
QLabel *lblStatus;
QPushButton *btnQuit;
QPushButton *btnStart;
QPushButton *btnStop;
QTcpSocket *serverSocket;
QTcpServer *tcpServer;
QTextEdit *teMessage;
};
#endif
Source file:
#include <QtGui>
#include <QtNetwork>
#include <QBuffer>
#include <stdlib.h>
#include "server.h"
Server::Server(QWidget *parent)
: QDialog(parent)
{
lblPort = new QLabel(tr("Port:"));
lePort = new QLineEdit;
QRegExp regExp("[1-9][0-9]{0,4}");
lePort->setValidator(new QRegExpValidator(regExp, this));
lblPort->setBuddy(lePort);
btnStart = new QPushButton(tr("Start"));
btnStop = new QPushButton(tr("Stop"));
btnStart->setDisabled(true);
btnStop->setDisabled(true);
QGroupBox *gbServerControl = new QGroupBox(tr("Server Control"));
QGroupBox *gbMessage = new QGroupBox(tr("Message"));
QGroupBox *gbConnectedClient = new QGroupBox(tr("Connected Client"));
twClientConnected = new QTreeWidget();
twClientConnected->setColumnCount(2);
slTreeLabel << tr("Address") << tr("Port");
twClientConnected->setHeaderLabels(slTreeLabel);
twClientConnected->header()->setStretchLastSection(false);
twClientConnected->header()->setResizeMode(QHeaderView::Stretch);
liClients.append(new QTreeWidgetItem(twClientConnected, QStringList(QString(""))));
twClientConnected->addTopLevelItems(liClients);
twClientConnected->takeTopLevelItem(0);
twClientConnected->takeTopLevelItem(0);
lblStatus = new QLabel;
lblStatus->setFrameShape(QLabel::Panel);
lblStatus->setFrameShadow(QLabel::Sunken);
lblStatus->setText(tr("Ready"));
btnQuit = new QPushButton(tr("Quit"));
btnQuit->setAutoDefault(false);
teMessage = new QTextEdit(this);
teMessage->setReadOnly(true);
tcpServer = new QTcpServer(this);
serverSocket = new QTcpSocket(this);
connect(lePort, SIGNAL(textChanged(QString)), this, SLOT(slotStartButtonEnable()));
connect(btnStart, SIGNAL(clicked()), this, SLOT(slotStartClicked()));
connect(btnStop, SIGNAL(clicked()), this, SLOT(slotStopClicked()));
connect(btnQuit, SIGNAL(clicked()), this, SLOT(close()));
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(slotNewClient()));
QHBoxLayout *portLayout = new QHBoxLayout;
portLayout->addWidget(lblPort);
portLayout->addWidget(lePort);
portLayout->addStretch(1);
portLayout->addWidget(btnStart);
portLayout->addWidget(btnStop);
gbServerControl->setLayout(portLayout);
QHBoxLayout *clientLayout = new QHBoxLayout;
clientLayout->addWidget(twClientConnected);
gbConnectedClient->setLayout(clientLayout);
QHBoxLayout *messageLayout = new QHBoxLayout;
messageLayout->addWidget(teMessage);
gbMessage->setLayout(messageLayout);
QHBoxLayout *bottomLayout = new QHBoxLayout;
bottomLayout->addWidget(lblStatus, 1);
bottomLayout->addWidget(btnQuit);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(gbServerControl);
mainLayout->addWidget(gbConnectedClient);
mainLayout->addWidget(gbMessage);
mainLayout->addLayout(bottomLayout);
setLayout(mainLayout);
setWindowTitle(tr("TCP Chat Server - by Strife Low"));
lePort->setFocus();
}
Server::~Server()
{
}
void Server::sendToClients(const QByteArray& line)
{
foreach (QTcpSocket* connection, connections)
{
connection->write(line);
}
}
void Server::slotStartButtonEnable()
{
btnStart->setDisabled(false);
}
void Server::slotStartClicked()
{
lblStatus->setText(tr("Server starting"));
if (lePort->text() == "")
{
QMessageBox::critical(this, tr("Server"), tr("Please enter a valid port number"));
return;
}
if (lePort->text().toInt() > 65535)
{
lePort->setText("65535");
}
if (!tcpServer->listen(QHostAddress::Any, lePort->text().toInt())) {
QMessageBox::critical(this, tr("Server"), tr("Unable to start the server: %1.").arg(tcpServer->errorString()));
return;
}
btnStart->setDisabled(true);
btnStop->setDisabled(false);
lePort->setDisabled(true);
lblStatus->setText(tr("Server started at port %1").arg(tcpServer->serverPort()));
}
void Server::slotStopClicked()
{
btnStart->setEnabled(true);
btnStop->setEnabled(false);
lePort->setDisabled(false);
if (tcpServer->isListening())
{
tcpServer->close();
}
if (!connections.isEmpty())
{
foreach (QTcpSocket* connection, connections)
{
connection->close();
}
connections.clear();
}
if (serverSocket->isValid())
{
serverSocket->close();
}
lblStatus->setText(tr("Server stopped"));
}
void Server::slotNewClient()
{
if (!connections.isEmpty())
{
QByteArray msg = "New Client connected\n";
foreach (QTcpSocket* connection, connections)
{
connection->write(msg);
}
}
serverSocket = tcpServer->nextPendingConnection();
QStringList tmpClientAddressPort;
tmpClientAddressPort << tr("%1").arg(serverSocket->peerAddress().toString()) << tr("%1").arg(serverSocket->peerPort());
liClients.append(new QTreeWidgetItem(twClientConnected, tmpClientAddressPort));
//itemList.insert(serverSocket, (liClients.count() - 1));
//tmpClientAddressPort.clear();
connections.append(serverSocket);
QBuffer* buffer = new QBuffer(this);
buffer->open(QIODevice::ReadWrite);
buffers.insert(serverSocket, buffer);
connect(serverSocket, SIGNAL(disconnected()), this, SLOT(slotClientDisconnected()));
connect(serverSocket, SIGNAL(readyRead()), this, SLOT(slotSocketRead()));
}
void Server::slotClientDisconnected()
{
QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
QBuffer* buffer = buffers.take(socket);
buffer->close();
buffer->deleteLater();
connections.removeAll(socket);
socket->deleteLater();
QByteArray msg = "Client disconnected\n";
foreach (QTcpSocket* connection, connections)
{
connection->write(msg);
}
}
void Server::slotSocketRead()
{
QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
QBuffer* buffer = buffers.value(socket);
qint64 bytes = buffer->write(socket->readAll());
buffer->seek(buffer->pos() - bytes);
while (buffer->canReadLine())
{
QByteArray line = buffer->readLine();
sendToClients(line);
teMessage->append(line);
}
}
// end of file
Header file:
#ifndef SERVER_H
#define SERVER_H
#include <QDialog>
#include <QList>
#include <QHash>
class QLabel;
class QPushButton;
class QTcpSocket;
class QTextEdit;
class QTcpServer;
class QLineEdit;
class QBuffer;
class QStringList;
class QTreeWidget;
class QTreeWidgetItem;
class Server : public QDialog
{
Q_OBJECT
public:
Server(QWidget *parent = 0);
~Server();
protected:
void sendToClients(const QByteArray& line);
private slots:
//void sendMessage();
void slotStartButtonEnable();
void slotStartClicked();
void slotStopClicked();
void slotNewClient();
void slotClientDisconnected();
void slotSocketRead();
private:
QList<QTcpSocket*> connections;
QHash<QTcpSocket*, QBuffer*> buffers;
//QHash<QTcpSocket*, int> itemList;
QList<QTreeWidgetItem *> liClients;
QTreeWidget *twClientConnected;
QStringList slTreeLabel;
QLineEdit *lePort;
QLabel *lblPort;
QLabel *lblStatus;
QPushButton *btnQuit;
QPushButton *btnStart;
QPushButton *btnStop;
QTcpSocket *serverSocket;
QTcpServer *tcpServer;
QTextEdit *teMessage;
};
#endif
Source file:
#include <QtGui>
#include <QtNetwork>
#include <QBuffer>
#include <stdlib.h>
#include "server.h"
Server::Server(QWidget *parent)
: QDialog(parent)
{
lblPort = new QLabel(tr("Port:"));
lePort = new QLineEdit;
QRegExp regExp("[1-9][0-9]{0,4}");
lePort->setValidator(new QRegExpValidator(regExp, this));
lblPort->setBuddy(lePort);
btnStart = new QPushButton(tr("Start"));
btnStop = new QPushButton(tr("Stop"));
btnStart->setDisabled(true);
btnStop->setDisabled(true);
QGroupBox *gbServerControl = new QGroupBox(tr("Server Control"));
QGroupBox *gbMessage = new QGroupBox(tr("Message"));
QGroupBox *gbConnectedClient = new QGroupBox(tr("Connected Client"));
twClientConnected = new QTreeWidget();
twClientConnected->setColumnCount(2);
slTreeLabel << tr("Address") << tr("Port");
twClientConnected->setHeaderLabels(slTreeLabel);
twClientConnected->header()->setStretchLastSection(false);
twClientConnected->header()->setResizeMode(QHeaderView::Stretch);
liClients.append(new QTreeWidgetItem(twClientConnected, QStringList(QString(""))));
twClientConnected->addTopLevelItems(liClients);
twClientConnected->takeTopLevelItem(0);
twClientConnected->takeTopLevelItem(0);
lblStatus = new QLabel;
lblStatus->setFrameShape(QLabel::Panel);
lblStatus->setFrameShadow(QLabel::Sunken);
lblStatus->setText(tr("Ready"));
btnQuit = new QPushButton(tr("Quit"));
btnQuit->setAutoDefault(false);
teMessage = new QTextEdit(this);
teMessage->setReadOnly(true);
tcpServer = new QTcpServer(this);
serverSocket = new QTcpSocket(this);
connect(lePort, SIGNAL(textChanged(QString)), this, SLOT(slotStartButtonEnable()));
connect(btnStart, SIGNAL(clicked()), this, SLOT(slotStartClicked()));
connect(btnStop, SIGNAL(clicked()), this, SLOT(slotStopClicked()));
connect(btnQuit, SIGNAL(clicked()), this, SLOT(close()));
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(slotNewClient()));
QHBoxLayout *portLayout = new QHBoxLayout;
portLayout->addWidget(lblPort);
portLayout->addWidget(lePort);
portLayout->addStretch(1);
portLayout->addWidget(btnStart);
portLayout->addWidget(btnStop);
gbServerControl->setLayout(portLayout);
QHBoxLayout *clientLayout = new QHBoxLayout;
clientLayout->addWidget(twClientConnected);
gbConnectedClient->setLayout(clientLayout);
QHBoxLayout *messageLayout = new QHBoxLayout;
messageLayout->addWidget(teMessage);
gbMessage->setLayout(messageLayout);
QHBoxLayout *bottomLayout = new QHBoxLayout;
bottomLayout->addWidget(lblStatus, 1);
bottomLayout->addWidget(btnQuit);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(gbServerControl);
mainLayout->addWidget(gbConnectedClient);
mainLayout->addWidget(gbMessage);
mainLayout->addLayout(bottomLayout);
setLayout(mainLayout);
setWindowTitle(tr("TCP Chat Server - by Strife Low"));
lePort->setFocus();
}
Server::~Server()
{
}
void Server::sendToClients(const QByteArray& line)
{
foreach (QTcpSocket* connection, connections)
{
connection->write(line);
}
}
void Server::slotStartButtonEnable()
{
btnStart->setDisabled(false);
}
void Server::slotStartClicked()
{
lblStatus->setText(tr("Server starting"));
if (lePort->text() == "")
{
QMessageBox::critical(this, tr("Server"), tr("Please enter a valid port number"));
return;
}
if (lePort->text().toInt() > 65535)
{
lePort->setText("65535");
}
if (!tcpServer->listen(QHostAddress::Any, lePort->text().toInt())) {
QMessageBox::critical(this, tr("Server"), tr("Unable to start the server: %1.").arg(tcpServer->errorString()));
return;
}
btnStart->setDisabled(true);
btnStop->setDisabled(false);
lePort->setDisabled(true);
lblStatus->setText(tr("Server started at port %1").arg(tcpServer->serverPort()));
}
void Server::slotStopClicked()
{
btnStart->setEnabled(true);
btnStop->setEnabled(false);
lePort->setDisabled(false);
if (tcpServer->isListening())
{
tcpServer->close();
}
if (!connections.isEmpty())
{
foreach (QTcpSocket* connection, connections)
{
connection->close();
}
connections.clear();
}
if (serverSocket->isValid())
{
serverSocket->close();
}
lblStatus->setText(tr("Server stopped"));
}
void Server::slotNewClient()
{
if (!connections.isEmpty())
{
QByteArray msg = "New Client connected\n";
foreach (QTcpSocket* connection, connections)
{
connection->write(msg);
}
}
serverSocket = tcpServer->nextPendingConnection();
QStringList tmpClientAddressPort;
tmpClientAddressPort << tr("%1").arg(serverSocket->peerAddress().toString()) << tr("%1").arg(serverSocket->peerPort());
liClients.append(new QTreeWidgetItem(twClientConnected, tmpClientAddressPort));
//itemList.insert(serverSocket, (liClients.count() - 1));
//tmpClientAddressPort.clear();
connections.append(serverSocket);
QBuffer* buffer = new QBuffer(this);
buffer->open(QIODevice::ReadWrite);
buffers.insert(serverSocket, buffer);
connect(serverSocket, SIGNAL(disconnected()), this, SLOT(slotClientDisconnected()));
connect(serverSocket, SIGNAL(readyRead()), this, SLOT(slotSocketRead()));
}
void Server::slotClientDisconnected()
{
QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
QBuffer* buffer = buffers.take(socket);
buffer->close();
buffer->deleteLater();
connections.removeAll(socket);
socket->deleteLater();
QByteArray msg = "Client disconnected\n";
foreach (QTcpSocket* connection, connections)
{
connection->write(msg);
}
}
void Server::slotSocketRead()
{
QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
QBuffer* buffer = buffers.value(socket);
qint64 bytes = buffer->write(socket->readAll());
buffer->seek(buffer->pos() - bytes);
while (buffer->canReadLine())
{
QByteArray line = buffer->readLine();
sendToClients(line);
teMessage->append(line);
}
}
// end of file