PDA

View Full Version : QTcpsocket Problem - unable to read written data to socket



bmoqimi
18th October 2010, 17:03
hello there ,

I am writing an accounting open source project for my course.it is finished but by no means I can transfer data between client and server.the qdebug days the data is written to the socket but on the other side I can not read that.I put all the codes in files in the attachments.
the code is small but is very important to me.
even if you do not have time you can look the code and suggest a better way of writing the client/multi threaded server.
most of the code is copied from fortune server/client.
you can make it using qmake ;)

Thank you in advance

bmoqimi
18th October 2010, 17:07
and here are some parts of the code in case you do not want to open the file.

this will be the client




FreeCafe_Client::FreeCafe_Client()
:QWidget(), currentState(Disconnected)
{
qDebug("FreeCafe_Client::FreeCafe_Client");
setAttribute(Qt::WA_DeleteOnClose);
// setWindowFlags(Qt::WindowStaysOnTopHint);
// setWindowState(Qt::WindowFullScreen);
resize(QApplication::desktop()->screenGeometry().size());
settings = new QSettings("FSF", "FreeCafe", this);
createUi();
socket = new QTcpSocket(this);
connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)) ,
SLOT(slotStateChanged(QAbstractSocket::SocketState )) );
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
SLOT(slotError(QAbstractSocket::SocketError)));
connect(socket, SIGNAL(readyRead()),this,
SLOT(slotReadyRead()));
connect(socket, SIGNAL(connected()),SLOT(authorize()));

QNetworkConfigurationManager manager;
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequir ed) {
// 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();
}

networkSession = new QNetworkSession(config, this);
connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened()));

qDebug("Opening network session.");
networkSession->open();
}
}

FreeCafe_Client::~FreeCafe_Client()
{}

void FreeCafe_Client::createUi()
{
qDebug("FreeCafe_Client::createUi");
QWidget *wd = new QWidget(this);
ui.setupUi(wd);
QHBoxLayout *h = new QHBoxLayout(this);
// h->addSpacerItem(new QSpacerItem(40, 40));//, QSizePolicy::MinimumExpanding));
h->addWidget(wd);
// h->addSpacerItem(new QSpacerItem(40, 40));//, QSizePolicy::MinimumExpanding));
connect(ui.btnLogin, SIGNAL(clicked()), SLOT(login()));
ui.server->setText(settings->value("lastHostIP", QString("127.0.0.1")).toString());
}

void FreeCafe_Client::login()
{
qDebug("FreeCafe_Client::login");
socket->abort();
QString host;
if(ui.server->text().isEmpty())
host = HOST;
else
host = ui.server->text();
socket->connectToHost(host, PORT);
settings->setValue("lastHostIP", ui.server->text());
}

void FreeCafe_Client::slotStateChanged(QAbstractSocket: :SocketState newState)
{
qDebug()<<"FreeCafe_Client::slotStateChanged: "<<newState;
if (newState == QAbstractSocket::ConnectedState)
{ authorize(); }
}

void FreeCafe_Client::authorize()
{
qDebug("FreeCafe_Client::authorize");
currentState = Connecting;
QByteArray data;
QByteArray block;

data = block = ui.username->text().toAscii() + ':' + ui.password->text().toAscii();
QDataStream out(&block, QIODevice::WriteOnly);

out.setVersion(QDataStream::Qt_4_0);
out << data;
socket->write(block);
qDebug()<<"Data sent to server: "<<data<<" size: "<<socket->write(block);

// socket->waitForReadyRead();//I think we can use this function and continue the process here, Instead of using the signal and FreeCafe_Client::slotReadyRead()

}

void FreeCafe_Client::slotError(QAbstractSocket::Socket Error socketError)
{
qDebug()<<"FreeCafe_Client::slotError"<< socketError;
}

void FreeCafe_Client::slotReadyRead()
{
qDebug("FreeCafe_Client::slotReadyRead");
if(currentState == Connecting){
bool ok;
QByteArray data = socket->readAll();
int res = data.toInt(&ok);
qDebug()<< QString::number(res);
if(ok){
if(res == -1){
QMessageBox::critical(this, tr("Wrong username/password"),
tr("username or password is wrong."));
} else if(res == 0){
QMessageBox::critical(this, tr("No credit"),
tr("You do not have enough credit to use this service."));
} else {
MainWindow *f = new MainWindow(res, this->socket, this->networkSession);
f->show();
close();
}
} else {
qDebug()<<"Malformed response: "<<data;
QMessageBox::critical(this, tr("Malformed response"),
tr("The data returned from server is not valid."));
}

} else if (currentState == Disconnected) {

QDataStream in(socket);
in.setVersion(QDataStream::Qt_4_0);

qDebug()<<"FreeCafe_Client::slotReadyRead: currentState==Disconnected: "<<socket->bytesAvailable();

QString data;
in >> data;
qDebug()<<"FreeCafe_Client::slotReadyRead: "<<data;
if(data == "OK"){
authorize();
}
}
}

void FreeCafe_Client::sessionOpened()
{
qDebug("FreeCafe_Client::sessionOpened");
// 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();
}


and this will do the server,although it is a thread only.



CafeThread::CafeThread(int sDescriptor, QObject *parent) :
QThread(parent), socketDescriptor(sDescriptor), isConnectedToClient(false)
{
}

void CafeThread::run()
{
qDebug("CafeThread::run");
socket = new QTcpSocket;
if( !socket->setSocketDescriptor(socketDescriptor) ) {
emit error(socket->error());
qDebug()<<"CafeThread::run: ERROR: "<<socket->errorString();
return;
}
connect(socket, SIGNAL(readyRead()),this, SLOT(slotReadyRead()));
connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)) ,
SLOT(slotStateChanged(QAbstractSocket::SocketState )));
connect(this , SIGNAL(logintimer()), SLOT(slottimerstart()));
connect(&timer, SIGNAL(timeout()), SLOT(slotOneMinutePassed()));

QByteArray block;//This was for test
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << "OK";
qDebug()<<"CafeThread::run: Data sent from server: 'OK' size: "<<socket->write(block);
QByteArray data = socket->readAll();
qDebug()<<"CafeThread::slotReadyRead: data recieved:"<<data;
//QDataStream in(socket);
socket->write(block);//
}

void CafeThread::slotReadyRead()
{
qDebug("CafeThread::slotReadyRead");
QByteArray data = socket->readAll();
qDebug()<<"CafeThread::slotReadyRead: data recieved:"<<data;
QString credentials = QString::fromAscii(data);
QStringList userpass = credentials.split(':');
int credit = -1;
if(userpass.count() == 2){
qDebug("User/pass recieved from client");
QString username = userpass[0];
QString password = userpass[1];
QSqlQuery q;
this->user = username;
q.prepare("SELECT Name, password, credit FROM users WHERE Name=? AND password=?");
q.addBindValue(username);
q.addBindValue(password);
if(q.next()){
credit = q.value(2).toInt();
this->money = credit;
if(credit > 100){//User cannot login when its credit is less than 100
isConnectedToClient = true;
emit loggedIn(username, credit);
emit logintimer();
// char *tt = credit;//how should I convert this ? ERROR HERE
//socket->write(&credit,sizeof(credit));// DATA CAN NOT BE PUSHED TO CLIENT
}
} else {
credit = -1;
}
if(socket->write(QByteArray::number(credit)) == -1){
qDebug()<<socket->errorString();
}
}
if(credit < 10)
socket->close();
}

void CafeThread::slotStateChanged(QAbstractSocket::Sock etState newState)
{
qDebug()<< newState;
switch(newState){
case QAbstractSocket::ClosingState:
if(isConnectedToClient){
emit loggedOut(this->user, this->usedtime);
quit();
}
break;
case QAbstractSocket::UnconnectedState:
case QAbstractSocket::HostLookupState:
case QAbstractSocket::ConnectedState:dosomething();brea k;
case QAbstractSocket::ConnectingState:
case QAbstractSocket::BoundState:
case QAbstractSocket::ListeningState:
default:
break;
}
}


I have removed parts which are not concerned !