using socket descriptor to identify the clients connected to the Threded server
Hi
How to use the socketDescriptor to identify the clients currently connected to threaded server.
thread is created when any client is connected to the server..
void FortuneServer::incomingConnection(int socketDescriptor)
{
FortuneThread *thread = new FortuneThread(socketDescriptor);
..
thread->start();
}
... in run()
{
set the socket Descriptor for the tcpSocket..
connect(this->tcpSocket, SIGNAL(readyRead()), this, SLOT(ready1), Qt::UniqueConnection);
}
ready1()
{
read the request from the clients & serve....)
}
need to write a function which sends some information to all the connected clients...
how to do this..
Thanks
Re: using socket descriptor to identify the clients connected to the Threded server
To send a message to all clients, you'll need to keep a list of all connected clients.
Why do you want to use threads? Are the clients/server synchronous (blocking) or asynchronous (non-blocking)?
If you do not need synchronous connections, then do not use threads, just keep a list of the client sockets.
Edit:
Ohh... and do not add this line:
connect(this->tcpSocket, SIGNAL(readyRead()), this, SLOT(ready1), Qt::UniqueConnection);
in the run() function of a thread!
Add it to the constructor of your thread, or a function that sets the socket for that thread.
Re: using socket descriptor to identify the clients connected to the Threded server
Thanks for reply..
I need Asynchronous communication..
how can i connect multiple clients without using threads..
(My server has SQLite DB connection.. just information.. if it changes the conclusion of using thread or not using thread..)
& How to get the list of all connected clients..?
Re: using socket descriptor to identify the clients connected to the Threded server
In your server create a list for client connections.
QList<QTcpSocket *> clientConnections;
Then, when you receive an new incomming connection, add the socket to the clientConnections list.
Connect the most useful signals of the client socket to slots in your server. For example, disconnected() and readyRead().
Example:
Code:
void YourServer::incomingConnection(int socketDescriptor)
{
clientConnection->setSocketDescriptor(socketDescriptor);
clientConnections->append(clientConnection);
connect(clientConnection, SIGNAL(...), this, SLOT(...));
// send some welcome to your socket (example)
sendWelcome(clientConnection);
}
When you want to send something to all client connections:
Code:
void sendToAllConnections(...)
{
foreach
(QTcpSocket *clientConnection, clientConnections
) { clientConnection->write(...);
}
etc...
}
Re: using socket descriptor to identify the clients connected to the Threded server
Thanks a lot for the valuable suggestions, I will try multiple client connection without using threads.
but using threads it was working fine.. with some run time warnings.. like "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)" now whenconnect(this->tcpSocket, SIGNAL(readyRead()), this, SLOT(ready1), Qt::UniqueConnection); in the constructor of the thread the runtime warning vanished.. now in the run() i have only
{
while(1)
{
}
}
no other than this if i remove the while().. only first time it reads and write. i want to know the reasons & the logic.. can i ask u to put light on this or suggest me some resources where i will get the good knowledge.
Re: using socket descriptor to identify the clients connected to the Threded server
How to pass the list of clientConnections in sendToAllConnections functions
Re: using socket descriptor to identify the clients connected to the Threded server
You do not, it is already there.
In my example above, when I write
void sendToAllConnections(...)
I really meant:
void YourServer::sendToAllConnections(...)
You add QList<QTcpSocket *> clientConnections; to your server class. Then it is available in every method of that class. Basic C++
Code:
{
Q_OBJECT
public:
...
void sendToAllConnections(const QString& message);
private:
QList<QTcpSocket *> clientConnections;
}
void YourServer::sendToAllConnections(const QString& message)
{
...
// Be sure to also check if the list isn't empty etc...
}
Re: using socket descriptor to identify the clients connected to the Threded server
I have created a GUI project, in server class is i have imported QTcpServer & QTcpSocket. & using the incomingConnection() in this class. but this server is not able to read or write to the client.but there is connection established b/w client & server. few code lines to support this explanation..
server.h
namespace Ui {
class Server;
}
class Server : public QWidget {
Q_OBJECT
public:
protected:
void incomingConnection(int socketDescriptor);
private:
QTcpServer *tcpServer;
QTcpSocket *clientConnection;
private slots:
void Transactions();
};
server.cpp
tcpServer = new QTcpServer(this);
QHostAddress ipadd("..");
tcpServer->listen(ipadd, p.no)
void Server::incomingConnection(int socketDescriptor)
{
clientConnection = new QTcpSocket(this);
clientConnection->setSocketDescriptor(socketDescriptor);
connect(this->clientConnection, SIGNAL(readyRead()), this, SLOT(Transactions()));
clientConnection->write("Hello from Server to client");
}
void Server::Transactions()//to read & write back..
{
char buf[1024];
qint64 lineLength = clientConnection->read(buf, sizeof(buf));
if (lineLength != -1) {
}
}
Re: using socket descriptor to identify the clients connected to the Threded server
Please take at least a little bit of effort to check your code yourself.
If you do not see your error then I think it's better to start on something easier.
You do not receive data from a client because there is no client.
Connect the incomingConnection signal to your incomingConnection slot (which also should be defined as a slot).
This is VERY basic!
Re: using socket descriptor to identify the clients connected to the Threded server
k but
if i declare incomingConnection as a slot it is telling
Object::connect: No such slot QTcpServer::incomingConnection(int) in server.cpp
as in qtcpserver.h this is defined as
protected:
virtual void incomingConnection(int handle);
Re: using socket descriptor to identify the clients connected to the Threded server
Here you go:
This will be much better, but check the code yourself as I didn't test it.
Code:
{
Q_OBJECT
public:
void sendToAllConnections(const QString& message);
private slots:
void slotNewConnection();
private:
QList<QTcpSocket *> clientConnections;
}
YourServer
::YourServer(QObject *parent
){
connect(this, SIGNAL(newConnection()), this, SLOT(slotNewConnection()));
}
void YourServer::slotNewConnection()
{
while (hasPendingConnections()) {
clientConnection = nextPendingConnection();
clientConnections->append(clientConnection);
connect(clientConnection, SIGNAL(...), this, SLOT(...));
}
}
void YourServer::sendToAllConnections(const QString& message)
{
foreach
(QTcpSocket *clientConnection, clientConnections
) { clientConnection->write(message.toUtf8());
}
}
Re: using socket descriptor to identify the clients connected to the Threded server
Thanks, the code works with bit modifications, for single client.. when many clients are connected there is the problem.. first time when client is connected it communicates(reads.. writes) properly. next one more client is connected server communicates with the second client properly... now after this when again the first client wants to communicate.. Server is not reading the data sent by this client. but the connection is there b/w server & first client.. as it keeps sending the data.(sendToAllConnections() is connected to a timer event).
Re: using socket descriptor to identify the clients connected to the Threded server
My fault. I should have said this earlier.
You need to use a signal mapper to connect the readyRead signals.
Of, if you do not want to use a signal mapper, use the sender() function to get the socket that is sending the signal.
Re: using socket descriptor to identify the clients connected to the Threded server
Hi all!
An other question:
All incoming client connections are stored in a list, ok.
Method sendToAllConnections() is also ok.
But how do you remove a connection from the list? This happens if the connection was closed/disconnected.
For example:
3 incoming client, list size = 3. Now the second client is closed by e.g. itself. The list size is also 3, because only a reference was stored. That couses a crash with next sendToAllConnections() call.
I tried to store the clients in a map with clients socketDescriptor as key. But if the QTcpClient::disconnected() is emitted the descriptor is already invalid (-1).
That's strange, I don't know how I can keep valid my list of connected clients.
Any suggestions?
Re: using socket descriptor to identify the clients connected to the Threded server
http://www.qtcentre.org/wiki/index.p...hout_threading
Code:
void MultiClientServer::clientDisconnected()
{
QTcpSocket *client
= qobject_cast<QTcpSocket
*>
(sender
());
if (!client)
return;
clientConnections.removeAll(client);
client->deleteLater();
}
Re: using socket descriptor to identify the clients connected to the Threded server
Re: using socket descriptor to identify the clients connected to the Threded server
Quote:
Originally Posted by
tbscope
It seems that the QTcpSocket does not have an implementation of operator==(), does anyone know if the removeAll method of QList (which as stated in the docs: "requires the value type to have an implementation of operator==()") can still find (and therefore remove) the passed socket ?
And would the answer also apply to a QSslSocket?
Many Thanks
_andrea
Re: using socket descriptor to identify the clients connected to the Threded server
hi
how can i write i msg to specific clientConnection which are saved in list of clientConnections.??instead of clientConnection->write("");
is there i way to use value of list to specify a client insted of sending a msg to each incoming connection??
Re: using socket descriptor to identify the clients connected to the Threded server
QList has an index operator and an at() method that both allow you to address a specific element in the list.
Cheers,
_
Re: using socket descriptor to identify the clients connected to the Threded server
i have tried .at() as following but i got an error:
QTcpSocket *clientConnection = new QTcpSocket;
clientConnection->setSocketDescriptor(socketDescriptor);
clientConnections.append(clientConnection);
QTcpSocket clientConnection0 =clientConnections.at(1);
error:24: error: conversion from ‘QTcpSocket* const’ to non-scalar type ‘QTcpSocket’ requested
Added after 16 minutes:
i tried
clientConnections.at(0)->write("hello");
but i got error index out of range
so how can specify the range in Qlist ,so latter i can use specific index of socket to write msg.
what im trying to do is 1.accept incoming connection in server side
2.keep a list of all connected socket..and do not write() msg immediately after accepting the connection unless pressing push button for example,
can you help me plz