Witam.
Piszę prostą aplikację klient-serwer, gdzie do serwera może podłączyć się kilku klientów. Każde połączenie klienta do serwera tworzy nowy wątek, w którym tworzony jest obiekt QTcpSocket. Później będę chciał co jakiś czas wysyłać z serwera jakiś string do wszystkich klientów, co ma być zsynchronizowane. Aktualnie tkwię na etapie, że nie wysyła mi 10 znaków "X" co sekundę do jednego klienta, tylko po 10 sekundach wyświetla wszystkie. Poniżej zamieszczam kody źródłowe. Proszę o jakieś podpowiedzi.
plik Server.cpp z aplikacji serwera:
#include "Server.h"
Server::Server(QObject *parent):QTcpServer(parent)
{
connect(this,SIGNAL(newConnection()),this,SLOT(addConnection()));
}
Server::~Server(void)
{
}
void Server::addConnection()
{
QTcpSocket *client = this->nextPendingConnection();
ClientThread *thread = new ClientThread(client->socketDescriptor(),text,this);
threadsList.push_back(thread);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
clientsList.push_back(client);
connect(client, SIGNAL(disconnected()), this, SLOT(removeConnection()));
connect(client, SIGNAL(disconnected()), client, SLOT(deleteLater()));
emit added(client->localAddress().toString());
}
void Server::removeConnection()
{
QTcpSocket* client = (QTcpSocket*)sender();
int index = clientsList.indexOf(client);
clientsList.removeAt(index);
threadsList.at(index)->terminate();
threadsList.removeAt(index);
emit removed(client->localAddress().toString());
client->close();
}
void Server::broadcast()
{
for(int i=0;i<clientsList.size();i++)
{
clientsList.at(i)->write("Twoja stara szybko idzie");
}
}
bool Server::start(int port)
{
if(!this->listen(QHostAddress::Any,port))
return false;
QString ipAddress;
QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
for(int i=0;i<ipAddressesList.size();i++)
{
if(ipAddressesList.at(i)!=QHostAddress::LocalHost && ipAddressesList.at(i).toIPv4Address())
{
ipAddress = ipAddressesList.at(i).toString();
break;
}
}
if (ipAddress.isEmpty())
{
ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
}
return true;
}
void Server::stop()
{
while(!clientsList.isEmpty())
{
clientsList.last()->close();
}
this->close();
}
int Server::countClients()
{
return clientsList.size();
}
int Server::countThreads()
{
return threadsList.size();
}
plik ClientThread.cpp z aplikacji serwera:
#include "ClientThread.h"
ClientThread::ClientThread(int socketDescriptor,QString &str,QObject *parent):socketDescriptor(socketDescriptor),text(str),QThread(parent)
{
}
ClientThread::~ClientThread(void)
{
}
void ClientThread::run()
{
QTcpSocket tcpSocket;
if (!tcpSocket.setSocketDescriptor(socketDescriptor)) {
emit error(tcpSocket.error());
return;
}
for(int i=0;i<10;i++)
{
tcpSocket.write("X ");
sleep(1);
}
}
plik ClientApp.cpp z aplikacji klienta:
#include "clientapp.h"
ClientApp::ClientApp(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
ui.portEdit->setValidator(new QIntValidator(1, 65535, this));
tcpSocket = new QTcpSocket(this);
connect(ui.connectButton,SIGNAL(clicked()),this,SLOT(connectTo()));
connect(ui.disconnectButton,SIGNAL(clicked()),this,SLOT(disconnectFrom()));
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onStateChanged(QAbstractSocket::SocketState)));
}
ClientApp::~ClientApp()
{
}
void ClientApp::connectTo()
{
tcpSocket->abort();
tcpSocket->connectToHost("localhost", ui.portEdit->text().toInt());
}
void ClientApp::disconnectFrom()
{
//tcpSocket->disconnectFromHost();
tcpSocket->close();
}
void ClientApp::onReadyRead()
{
while(!tcpSocket->atEnd())
{
QString data(tcpSocket->read(2));
ui.textEdit->append("Serwer: " + data);
}
}
void ClientApp::onStateChanged(QAbstractSocket::SocketState socketState)
{
switch (socketState)
{
case QAbstractSocket::ConnectedState:
ui.connectButton->setEnabled(false);
ui.disconnectButton->setEnabled(true);
ui.textEdit->append("Nawiazano polaczenie z serwerem.");
break;
case QAbstractSocket::UnconnectedState:
ui.connectButton->setEnabled(true);
ui.disconnectButton->setEnabled(false);
ui.textEdit->append("Rozlaczono.");
break;
case QAbstractSocket::HostLookupState:
ui.textEdit->append("Szukanie serwera.");
break;
case QAbstractSocket::ConnectingState:
ui.textEdit->append("Laczenie z serwerem.");
break;
}
}