ich habe wieder ein Problem mit meinem selbst geschriebenem Chatprogramm.
Das Verbinden klappt soweit, allerdings soll der Client die Verbindung auch trennen können. Dazu sendet er QUIT an den Server, wenn man auf Trennen klickt. Der Server registriert, dass Daten ankommen, zeigt dann aber nichts an.
SERVER
italk.h
Code: Alles auswählen
#ifndef italk_H
#define italk_H
#include "ui_italk.h"
#include "logfile.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <QtGui>
#include <QString>
#include <QTranslator>
#include <QTimer>
#include <QKeyEvent>
#include <QtNetwork>
#include <QDataStream>
#include <QByteArray>
#include <QHostAddress>
#include <QAbstractSocket>
#include <QTcpSocket>
#include <QTcpServer>
using namespace std;
class italk : public QMainWindow, public Ui::MainWindow
{
Q_OBJECT
public:
italk(QMainWindow *parent = 0);
~italk();
private slots:
void showAbout();
void setServerOnline();
void newClient();
void recieveCommand();
private:
QTcpServer *dataServer;
QTcpServer *commandServer;
QTcpSocket *commandSocket;
QTcpSocket *dataSocket;
};
#endifCode: Alles auswählen
#include "italk.h"
italk::italk(QMainWindow *parent) : QMainWindow(parent)
{
setupUi(this);
connect(actionAbout, SIGNAL (triggered()), this, SLOT(showAbout()));
connect(actionAboutQt, SIGNAL (triggered()), qApp, SLOT(aboutQt()));
setServerOnline();
}
italk::~italk()
{
}
void italk::showAbout()
{
QMessageBox aboutBox;
aboutBox.about(this, QString(tr("Info")), QString(tr("Infotext")));
}
void italk::setServerOnline()
{
dataServer = new QTcpServer(this);
commandServer = new QTcpServer(this);
dataServer->listen(QHostAddress::Any,51239);
commandServer->listen(QHostAddress::Any,51238);
connect(commandServer, SIGNAL(newConnection()), this, SLOT(newClient()));
}
void italk::newClient()
{
cout << "Neuer Client hat die Verbindung aufgenommen" << endl;
if (commandServer->hasPendingConnections())
{
commandSocket = commandServer->nextPendingConnection();
connect(commandSocket, SIGNAL(readyRead()), this, SLOT(recieveCommand()));
}
}
void italk::recieveCommand()
{
while (commandSocket->canReadLine())
{
if(QString(commandSocket->readLine()).startsWith("NEW"))
{
cout << "Neuer Client sendete NEW und versucht, sich am Server anzumelden..." << endl;
commandSocket->write("OK\n");
commandSocket->flush();
cout << "Client hat sich erfolgreich am Server angemeldet." << endl;
}
if(QString(commandSocket->readLine()).startsWith("QUIT"))
{
cout << "Client sendete QUIT und wird vom Server getrennt..." << endl;
commandSocket->write("QUIT\n");
commandSocket->flush();
cout << "Client wurde vom Server getrennt." << endl;
}
else
cout << "unbekannter Befehl: " << QString(commandSocket->readAll()).toStdString() << endl;
}
}
CLIENT
italk.h
Code: Alles auswählen
#ifndef italk_H
#define italk_H
#include "ui_italk.h"
#include "settings.h"
#include "connections.h"
#include "connectionssettings.h"
#include "logfile.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <QtGui>
#include <QTimer>
#include <QString>
#include <QTranslator>
#include <QKeyEvent>
#include <QtNetwork>
#include <QDataStream>
#include <QByteArray>
#include <QHostAddress>
#include <QAbstractSocket>
#include <QTcpSocket>
using namespace std;
class italk : public QMainWindow, public Ui::MainWindow
{
Q_OBJECT
public:
italk(QMainWindow *parent=0);
~italk();
private slots:
void connectToServer();
void setUpConnection();
void resetConnection();
void quitFromServer();
void disconnectFromServer();
void showConnectionError(QAbstractSocket::SocketError socketError);
void sendData();
void readData();
void sendCommand();
void readCommand();
void showNotification(int event, QString user);
void keyPressEvent(QKeyEvent *keyEvent);
void showSettings();
void showConnections();
void showLogfile();
void showAbout();
void loadSettings();
void loadConnections();
private:
QTcpSocket *dataSocket;
QTcpSocket *commandSocket;
QTimer *serverTimeout;
bool enterFocus;
QString setting[9];
QString connection[10][3];
int dataSet;
int entry;
};
#endif
Code: Alles auswählen
#include "italk.h"
italk::italk(QMainWindow *parent) : QMainWindow(parent)
{
setupUi(this);
loadSettings();
loadConnections();
connect(actionSettings, SIGNAL (triggered()), this, SLOT(showSettings()));
connect(actionConnections, SIGNAL (triggered()), this, SLOT(showConnections()));
connect(actionLogfile, SIGNAL (triggered()), this, SLOT(showLogfile()));
connect(actionAbout, SIGNAL (triggered()), this, SLOT(showAbout()));
connect(actionAboutQt, SIGNAL (triggered()), qApp, SLOT(aboutQt()));
connect(actionQuit, SIGNAL (triggered()), qApp, SLOT(quit()));
connect(connectButton, SIGNAL (clicked()), this, SLOT(connectToServer()));
connect(disconnectButton, SIGNAL (clicked()), this, SLOT(quitFromServer()));
connect(sendButton, SIGNAL (clicked()), this, SLOT(sendData()));
sendButton->setEnabled(FALSE);
runButton->setEnabled(FALSE);
disconnectButton->setEnabled(FALSE);
messageEdit->setEnabled(FALSE);
runEdit->setEnabled(FALSE);
messageTextBox->setReadOnly(TRUE);
nicknameEdit->setFocus();
enterFocus=TRUE;
connectionStatusBar->showMessage(QString(tr("Nicht verbunden.")));
}
italk::~italk()
{
}
void italk::connectToServer()
{
if (nicknameEdit->text().trimmed().length()<=64 && !nicknameEdit->text().trimmed().isEmpty())
{
QString command("NEW###"+nicknameEdit->text().trimmed()+"\n");
commandSocket = new QTcpSocket(this);
serverTimeout = new QTimer(this);
connect(commandSocket, SIGNAL(readyRead()), this, SLOT(readCommand()));
connect(commandSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(showConnectionError(QAbstractSocket::SocketError)));
connect(serverTimeout, SIGNAL(timeout()), this, SLOT(resetConnection()));
commandSocket->connectToHost("127.0.0.1", 51238);
connectionStatusBar->showMessage(QString(tr("Anfrage an Server %1.")) .arg(commandSocket->peerName()));
if (commandSocket->waitForConnected(10000))
{
commandSocket->write(command.toAscii().data());
serverTimeout->start(10000);
}
else
{
QMessageBox errorBox;
errorBox.critical(this, QString(tr("Fehler")), QString(tr("<b>Server antwortet nicht</b><br/>Der Server hat in der gegebenen Zeit nicht geantwortet. Bitte versuchen Sie es später noch einmal.")));
resetConnection();
}
}
else
{
if(nicknameEdit->text().trimmed().isEmpty())
{
QMessageBox errorBox;
errorBox.warning(this, QString(tr("Warnung")), QString(tr("<b>Eingabefeld leer</b><br/>Sie haben keinen Nicknamen angegeben.")));
}
else
{
QMessageBox errorBox;
errorBox.warning(this, QString(tr("Warnung")), QString(tr("<b>Nickname zu lang</b><br/>Der eingegebene Nickname ist zu lang.")));
}
}
}
void italk::setUpConnection()
{
serverTimeout->stop();
connectionStatusBar->showMessage(QString(tr("Server hat geantwortet...")));
dataSocket = new QTcpSocket(this);
connect(dataSocket, SIGNAL(readyRead()), this, SLOT(readData()));
dataSocket->connectToHost("127.0.0.1", 51239);
connectionStatusBar->showMessage(QString(tr("Verbindung hergestellt mit %1.")) .arg(dataSocket->peerName()));
sendButton->setEnabled(TRUE);
runButton->setEnabled(TRUE);
disconnectButton->setEnabled(TRUE);
connectButton->setEnabled(FALSE);
messageEdit->setEnabled(TRUE);
runEdit->setEnabled(TRUE);
nicknameEdit->setEnabled(FALSE);
connectionsBox->setEnabled(FALSE);
messageEdit->setFocus();
enterFocus=FALSE;
}
void italk::resetConnection()
{
// erstellte Objekte löschen bzw. zurücksetzten
// Statusbar eintrag ändern
}
void italk::quitFromServer()
{
commandSocket->write("QUIT\n");
commandSocket->flush();
}
void italk::disconnectFromServer()
{
dataSocket->close();
commandSocket->close();
connectionStatusBar->showMessage(QString(tr("Verbindung getrennt.")));
nicknameEdit->clear();
messageEdit->clear();
runEdit->clear();
messageTextBox->clear();
sendButton->setEnabled(FALSE);
runButton->setEnabled(FALSE);
disconnectButton->setEnabled(FALSE);
connectButton->setEnabled(TRUE);
messageEdit->setEnabled(FALSE);
runEdit->setEnabled(FALSE);
nicknameEdit->setEnabled(TRUE);
connectionsBox->setEnabled(TRUE);
nicknameEdit->setFocus();
enterFocus=TRUE;
}
void italk::showConnectionError(QAbstractSocket::SocketError socketError)
{
resetConnection();
switch (socketError)
{
case QAbstractSocket::RemoteHostClosedError:
break;
case QAbstractSocket::HostNotFoundError:
QMessageBox::information(this, tr("1"), tr("The host was not found. Please check the host name and port settings."));
break;
default:
QMessageBox::information(this, tr("3"), tr("The following error occurred: %1.") .arg(dataSocket->errorString()));
}
}
void italk::sendData()
{
if (messageEdit->text().trimmed().length()<=1024 && !messageEdit->text().trimmed().isEmpty())
{
QString message(messageEdit->text().trimmed());
dataSocket->write(message.toAscii());
dataSocket->flush();
messageEdit->clear();
}
else
{
if(messageEdit->text().trimmed().isEmpty())
{
QMessageBox errorBox;
errorBox.warning(this, QString(tr("Warnung")), QString(tr("<b>Eingabefeld leer</b><br/>Sie haben keine Nachricht eingegeben, die Sie versenden wollen.")));
}
else
{
QMessageBox errorBox;
errorBox.warning(this, QString(tr("Warnung")), QString(tr("<b>Nachricht zu lang</b><br/>Sie haben eine zu lange Nachricht eingegeben.")));
}
}
}
void italk::readData()
{
QString message(dataSocket->readAll());
if (message.endsWith("%%%") && !message.isEmpty())
{
message.remove(-3, 3 );
<b>"+self.data[1]+": </b>"+self.data[0]
message="<br/>"+message;
messageTextBox->insertHtml(message);
}
}
void italk::sendCommand()
{
}
void italk::readCommand()
{
while (commandSocket->canReadLine())
{
QString command(commandSocket->readLine());
if (command.startsWith("OK"))
setUpConnection();
if (command.startsWith("NEW"))
newUser(command);
if (command.startsWith("AWAY"))
userAway(command);
if (command.startsWith("QUIT"))
disconnectFromServer();
}
}
void italk::showNotification(int event, QString user)
{
if (event>=0 && event<=3)
{
if (setting[event+1]=="1")
{
if (setting[6]=="1")
{
cout << "Hinweiston" << endl;
}
if (setting[5]=="0")
{
cout << "KDE" << endl;
}
if (setting[5]=="1")
{
cout << "Gnome" << endl;
}
}
}
}
void italk::keyPressEvent(QKeyEvent *keyEvent)
{
if (keyEvent->key() == Qt::Key_Return)
{
if(enterFocus==TRUE)
{
connectToServer();
}
else
{
sendData();
}
}
}
void italk::showSettings()
{
settings dialog;
dialog.exec();
}
void italk::showConnections()
{
connections dialog;
dialog.exec();
}
void italk::showLogfile()
{
logfile dialog;
dialog.exec();
}
void italk::showAbout()
{
QMessageBox aboutBox;
aboutBox.about(this, QString(tr("Info")), QString(tr("Infotext")));
}
void italk::loadSettings()
{
dataSet=0;
QFile settingsFile("settings");
if (!settingsFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
QMessageBox errorBox;
errorBox.critical(this, QString(tr("Fehler")), QString(tr("<b>Einstellungsdatei nicht gefunden</b><br/>Die Einstellungsdatei konnte nicht gefunden werden. Daher werden die Standarteinstellungen verwendet und eine neue Datei mit den Standarteinstellungen angelegt.")));
setting[0]=QString("0");
setting[1]=QString("0");
setting[2]=QString("0");
setting[3]=QString("0");
setting[4]=QString("0");
setting[5]=QString("0");
setting[6]=QString("0");
setting[7]=QString("2");
}
QTextStream in(&settingsFile);
while (!in.atEnd())
{
QString line = in.readLine();
setting[dataSet]=line;
dataSet++;
}
settingsFile.close();
}
void italk::loadConnections()
{
dataSet=0;
QFile connectionsFile("connections");
if (!connectionsFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
QMessageBox errorBox;
errorBox.critical(this, QString(tr("Fehler")), QString(tr("<b>Verbindungsdatei nicht gefunden</b><br/>Die Verbindungsdatei konnte nicht gefunden werden. Daher wird eine neue Datei angelegt.")));
}
QTextStream in(&connectionsFile);
while (!in.atEnd())
{
for(entry=0; entry<3; entry++)
{
QString line = in.readLine();
connection[dataSet][entry]=line;
}
connectionsBox->insertItem(dataSet, QString(connection[dataSet][0]));
dataSet++;
}
connectionsFile.close();
connectionsBox->insertItem(dataSet, QString(tr("-")));
connectionsBox->insertItem(dataSet+1, QString(tr("Server nehmen, der online ist...")));
connectionsBox->insertItem(dataSet+2, QString(tr("Manuell mit Server verbinden...")));
}
Ich habe einfach keine Ahnung, warum das Versenden einmal funktioniert, und dann nicht mehr.