PDA

View Full Version : The server cannot write to the client. Why?



probine
23rd March 2006, 12:13
I have this simple code:
_____________________________
void ClientThread :: run()
{
QTcpSocket tcpSocket;
if(!tcpSocket.setSocketDescriptor(socketDescriptor ))
{
std::cout << "Error setting the socket descriptor\n";
return;
}
std::cout << "clientThread is running\n";
quint16 clientPort;
clientPort = tcpSocket.peerPort();
std::cout << "the client's port is: " << clientPort << "\n";
QByteArray block("hello there\n");
tcpSocket.write(block);
}
___________________________________________-
The server is suppose to say "hello there" to the client.

1. The client is a telnet that succesfully connects to the server, but it never receives the message from the server. Why ?

2. the connection is closed by the server. I want the connection to be alive all the time. How ?

wysota
23rd March 2006, 12:23
run() returns, the socket goes out of scope, the thread terminates. All that before anything is actually written to the socket. You must have some kind of loop in run() to keep it going.

jpn
23rd March 2006, 12:25
tcpSocket goes out of the scope, and since write is non-blocking, nothing gets written before the thread terminates..

probine
23rd March 2006, 13:39
I dont really understand it.

can you post some Code ?

wysota
23rd March 2006, 14:07
void Thread::run(){
QTcpSocket sock;
sock.setSocketDescriptor(socketDescriptor);
while(1){
QByteArray ba("test\n");
sock.write(ba);
sock.waitForBytesWritten(1000);
sleep(2);
}
}

probine
24th March 2006, 09:34
Thanks for your help. It is difficult to figure things out by just reading the documentation, though I am trying to leern.

Now my server is able to write a "Hello" message to the client, how about if the client wants to write to the server ? Where do I place the code ?

This is what I have so far:
__________________________________________________ _____
# include <QTcpSocket>
# include <iostream>

# include "client_thread.h"

ClientThread :: ClientThread(int socket_descriptor, QThread* parent) : QThread(parent)
{
std::cout << "Class ClientThread - Constructor\n";
this->socket_descriptor = socket_descriptor;
start();
}


void ClientThread :: run()
{
tcp_socket = new QTcpSocket();
if(!tcp_socket->setSocketDescriptor(socket_descriptor))
{
std::cout << "Class ClientThread - Function run() - error setting socket descriptor\n";
return;
}
quint16* client_port;
client_port = new quint16(tcp_socket->peerPort());
std::cout << "Class ClientThread - Funcion run\n";
std::cout << "The client's port is: " << *client_port << "\n";
QByteArray* message = new QByteArray("Hello\n");
tcp_socket->write(*message);
tcp_socket->waitForBytesWritten(1000);
}
__________________________________________________ ________

How can I have the server reading from client's messages ?

jpn
24th March 2006, 09:40
Take a look at the network examples (http://doc.trolltech.com/4.1/examples.html#network-examples) provided with Qt.
Especially the (Threaded) Fortune Server and Fortune Client example should be really useful for you.

probine
24th March 2006, 09:52
I am looking at the examples. There is one that allows a client to receive data from the server.

Here, a signal is emitted every time new data is arriving:

connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readFortune()));

I have also done that in my server, but the method "readMessage()" is never called, have a look:
__________________________________________________ _______________
# include <QTcpSocket>
# include <iostream>

# include "client_thread.h"

ClientThread :: ClientThread(int socket_descriptor, QThread* parent) : QThread(parent)
{
std::cout << "Class ClientThread - Constructor\n";
this->socket_descriptor = socket_descriptor;
start();
}


void ClientThread :: run()
{
tcp_socket = new QTcpSocket();
connect(tcp_socket, SIGNAL(readyRead()), this, SLOT(readMessage()));
if(!tcp_socket->setSocketDescriptor(socket_descriptor))
{
std::cout << "Class ClientThread - Function run() - error setting socket descriptor\n";
return;
}
quint16* client_port;
client_port = new quint16(tcp_socket->peerPort());
std::cout << "Class ClientThread - Funcion run\n";
std::cout << "The client's port is: " << *client_port << "\n";
QByteArray* message = new QByteArray("Hello\n");
tcp_socket->write(*message);
tcp_socket->waitForBytesWritten(1000);
}

void ClientThread :: readMessage()
{
std::cout << "Class ClientThread - Function readMessage()\n";
}
_______________________________________________--

Help ?

jpn
24th March 2006, 10:13
The thread dies after run() reaches its end. And this is right after you have waited enough for the bytes to get written. Take a look at the piece of code wysota gave you..

Oh, and use [ code ] tags around your code postings to make it more readable, please ;)

probine
24th March 2006, 14:15
what is the signal that QTcpServer should receive when a client wants to send data to the server ?

I am confused... please post some code if possible

wysota
24th March 2006, 14:47
You should thing about the design of the thread first as I have the impression that you don't know how should the thread behave. In the first place -- are you sure you need the thread at all?

probine
24th March 2006, 15:43
The idea:

The idea of the program is that the server will handle different clients. Everytime a client is connected to the server, this one will create a thread that will contain all the information about the client.

This thread will also be used to receive and send messages to the client.

When the client disconnects, then the thread dies.

wysota
24th March 2006, 17:14
I didn't mean "what the thread should do" but rather "how the thread should do it" -- design, not purpose.

You have to start by thinking -- "if I was the thread, how would I achieve the task, what would I need and why". Then you should think of each of the procedures the same way, just in more detail until you have the whole concept in your head of even on paper (this way you won't forget about anything). Then you can start thinking about the implementation itself (meaning, what modules of the environment I use will fit best to what I want to do).

Because as for now I don't see a reason to use threads at all... I would just hold the connections in some data structures and connect appropriate signals to custom slots and implement everything in an event driven way. But, of course, I don't know the nature of requests that are to be handled. Depending on what they are to be and how are they to be handled, it could be better to use threads.