PDA

View Full Version : threaded server for multiple clients writing to the client only first time



meena
7th May 2010, 11:45
Hello

I am writing the Threaded server where I can connect multiple clients, my server has DB(SQLite) connection.
Working: 1. First time whatever Server has written to the socket, Client is reading.
2. Server is reading whatever the client has written
Not Working: 1 As soon as i connect client to the Server, Message at server:
"QObject: Cannot create children for a parent that is in a different thread.
(Parent is FortuneThread(0x23bb7a0), parent's thread is QThread(0x1b166a0), current thread is FortuneThread(0x23bb7a0)"
2 Second time onwards whatever the server is writing client is not able to read.

what is wrong with the server code.. i feel no problem with the client , as it worked as desired with the Server without thread please guide..

Thanks

wysota
9th May 2010, 01:14
Please post your code which causes the warning to appear. And please explain why you want to use threads for handling the network.

meena
10th May 2010, 08:14
Thanks for replying..
Reason to use threads for Networking is .. I need to connect Multiple clients (100 to 1000) with the server.
Now I am able to connect to the DB & able to get the desired answer but only for once.. second time The server is not reading the request sent by the client. every time i need to press the get connected button of the client. but i am getting the message

QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed." + the original tread creation problem..

I am giving the code segment for Server & Client as well so that it will help u to understand. thanks for taking time to look in to the code...


Server::
void FortuneThread::run()
{
tcpSocket = new QTcpSocket(this);

if (!tcpSocket->setSocketDescriptor(socketDescriptor)) {
emit error(tcpSocket->error());
return;
}
qDebug()<<"Here Connection is established.. as newConnection signal is emitted";

createConnection();
model = new QSqlTableModel(this);
model->setTable("Users");
model->select();

tcpSocket->write("Hello from Server to Client");
tcpSocket->waitForBytesWritten(10000);
connect(this->tcpSocket, SIGNAL(readyRead()), this, SLOT(ready1()),Qt::DirectConnection);
tcpSocket->waitForReadyRead(10000);
}

void FortuneThread::ready1()
{

char buf[1024];
qint64 lineLength = tcpSocket->read(buf, sizeof(buf));
if (lineLength != -1) {
// the line is available in buf
}
printf("The rec string in threaded Server = %s\n", buf);
fflush(0);
QString s1 = buf;
if(s1 == "TotalUsers")
{
/* total Users */
qDebug()<<"I am in ready1";
QSqlQuery q1("select COUNT(UserID) as totalcount from Users");
QSqlRecord rec1 = q1.record();
int nameColl = rec1.indexOf("totalcount"); // index of the field "name"
QString j1;//int j1;
while (q1.next())
j1 = q1.value(nameColl).toString();//j1 = q1.value(nameColl).toInt();
/* total Users */

qDebug()<<"Total Number of Users are: j1 = :"<<j1;

/*char buf[30] = "Total Number of Users are: j1";
tcpSocket->write(buf, sizeof(buf));*/

tcpSocket->write(("Total Number of Users are :" + j1 ).toAscii().data());
tcpSocket->waitForBytesWritten(10000);

}else if(s1 == "UserInfo")
{
static int a;
/* total Users */
QSqlQuery q1("select COUNT(UserID) as totalcount from Users");
QSqlRecord rec1 = q1.record();
int nameColl = rec1.indexOf("totalcount"); // index of the field "name"
int j1;
while (q1.next())
j1 = q1.value(nameColl).toInt();
/* total Users */
QString j, k, l, m, jarr[j1], karr[j1], larr[j1], marr[j1], all_data;

QSqlQuery q("Select * from Users");
QSqlRecord rec = q.record();
int nameCol = rec.indexOf("UserID"); // index of the field "UserID"
int nameCol1 = rec.indexOf("UserName");
int nameCol2 = rec.indexOf("Verification");
int nameCol3 = rec.indexOf("PIN");

int i = 0;
while (q.next())
{
j = q.value(nameCol).toString();
k = q.value(nameCol1).toString();
l = q.value(nameCol2).toString();
m = q.value(nameCol3).toString();

qDebug() << "USerID = : " << j; // output number of records//qDebug consol o/p
qDebug() << "UserName = : " << k;
qDebug() << "Verification Method: " << l;
qDebug() << "PIN = : " << m;

jarr[i] = j;
karr[i] = k;
larr[i] = l;
marr[i] = m;
i++;

}

for( i = 0; i < j1; i++)
{
all_data += jarr[i] + "\t" + karr[i] + "\t" + larr[i] + "\t" + marr[i] + "\n";
}
tcpSocket->write((all_data).toAscii().data());//this statement writes the string to the socket
tcpSocket->waitForBytesWritten(10000);

}else if(s1 == "adduser/117/Manoj/FC/weqeqwe")
{
bool i;
int m=0;
QSqlQuery query;
/*QString userid = "117";
QString username = "Manoj";
QString verification = "FC";
QString pin = "weqeqwe";*/

QString userid = s1.section('/', 1,1);
QString username = s1.section('/', 2,2);
QString verification = s1.section('/', 3,3);
QString pin = s1.section('/', 4,4);

qDebug()<< "userid in server.cpp = " << userid;
qDebug()<< "username in server.cpp = " << username;
qDebug()<< "verification in server.cpp = " << verification;
qDebug()<< "pin in server.cpp = " << pin;

QString stat = QString("insert into Users values('%0', '%1' ,' %2',' %3')").arg(userid).arg(username).arg(verification).arg( pin);
i = query.exec(stat);

m = query.size();
printf("\n number of rows = %d\n", m);
if(!i)
{
QString message(tr("User is not addedd 1:User already exists 2:user id should be a number"));
qDebug()<<"User Not Added";

}else
{

QString message(tr("User added Successfully. "));
qDebug()<<"User Added";
}

}else if(s1 == "edit user 117 Manoj FC ManojPIN")
{
int i;
QSqlQuery query;
QString userid = "117";
QString username = "Manoj";
QString verification = "FC";
QString pin = "ManojPIN";
query.prepare("update Users set UserName = ?,Verification = ?,PIN = ? where UserID = ?");
query.addBindValue(username);
query.addBindValue(verification);
query.addBindValue(pin);
query.addBindValue(userid);
query.exec();

i = query.numRowsAffected();
if(i)
{
QString message(tr("User updated Successfully. "));
}else
{
qDebug()<<"UserID does not exist, cannot be edited.";
}

}else if(s1 == "delete user 117 Manoj FC ManojPIN")
{
QString userid = "117";
QString message(tr("User Deleted Successfully"));
QSqlQuery query;
QString string = QString("delete from Users where UserID= "+ userid);
query.exec(string);
tcpSocket->write("UserID 117 Deleted Successfully");
qDebug()<<"User Deleted";
}

}

client.cpp



{
ui->setupUi(this);

tcpsocket = new QTcpSocket(this);

connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(requestNewFortune()));
connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(close()));
this->setWindowTitle("Client");
}


void Client::requestNewFortune()
{
blockSize = 0;
tcpsocket->abort();
tcpsocket->connectToHost(ui->lineEdit->text(), ui->lineEdit_2->text().toInt());
connect(this->tcpsocket, SIGNAL(readyRead()), this, SLOT(readFortune()));
connect(this->tcpsocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
connect(ui->AddUserBtn, SIGNAL(clicked()), SLOT(sendUserDetails()));
connect(ui->EditUserBtn, SIGNAL(clicked()), SLOT(sendUserDetailstoEdit()));
connect(ui->DeleteUserBtn, SIGNAL(clicked()), SLOT(sendUserDetailstoDelete()));

connect(ui->TotalUserBtn, SIGNAL(clicked()), SLOT(GetTotalNumberofUsers()));
connect(ui->GetUserInfoBtn, SIGNAL(clicked()), SLOT(GetUserInfo()));
connect(ui->disconnect_Btn, SIGNAL(clicked()), SLOT(DisconnectFromServer()));
}

void Client::readFortune()
{
char cbuf[1024];
qint64 lineLength = tcpsocket->read(cbuf, sizeof(cbuf));
if (lineLength != -1) {
// the line is available in buf
}


ui->label_3->setText(cbuf);
}
void Client::displayError(QAbstractSocket::SocketError socketError)
{
switch (socketError) {
.....
}

}
void Client::sendUserDetails()
{
AddUser *idadduser = new AddUser(tcpsocket);
idadduser->exec();
}

void Client::GetTotalNumberofUsers()
{
char buf[12] = "TotalUsers";
qint64 lineLength = tcpsocket->write(buf, sizeof(buf));
}

void Client::GetUserInfo()
{
char buf[12] = "UserInfo";
tcpsocket->write(buf, sizeof(buf));
}

void Client::sendUserDetailstoEdit()
{
......
}

void Client::sendUserDetailstoDelete()
{
........
}

void Client::DisconnectFromServer()
{

tcpsocket->close();
}

wysota
10th May 2010, 08:22
Reason to use threads for Networking is .. I need to connect Multiple clients (100 to 1000) with the server.
This doesn't explain the use of threads.

Do you create a new database connection with a unique name for each thread?

meena
10th May 2010, 09:59
ok at this place the thread is created..

void FortuneServer::incomingConnection(int socketDescriptor)
{
FortuneThread *thread = new FortuneThread(socketDescriptor, fortune,this);
thread->start();
}

my understanding is whenever the new connection happens (a new client connects to the server)new thread is connected..

I am just trying to build my requirements on existing Threaded Fortune Server example.
yes currently creating a new database connection for each thread. any suggestion on DB connectivity please correct me.

wysota
10th May 2010, 10:49
Please post the contents of your createConnection() method.

meena
10th May 2010, 11:18
createConnection() is in database.h file & the method is exactly look like this

static bool createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(" ... ");
if (!db.open()) {
QMessageBox::critical(0, qApp->tr("Cannot open database"),
qApp->tr("Unable to establish a database connection.\n"
"This example needs SQLite support. Please read "
"the Qt SQL driver documentation for information how "
"to build it.\n\n"
"Click Cancel to exit."), QMessageBox::Cancel);
return false;
}

return true;
}

wysota
10th May 2010, 11:26
So you are not creating a new connection for each new thread, you are reusing the same connection name each time so only one thread at once is able to communicate with the database. And that's what Qt already told you, you even quoted the message in one of the first posts.