PDA

View Full Version : QSslSocket vs QTcpSocket problem



camol
4th March 2011, 16:01
Modified server1 code:

Modified test server2/client code: (removed)

I'm having trouble uploading through using SSL, a situation that in early server1 sends some 8842 bytes, and the server gives a two bytesAvaible just exactly what 4096 means that the code can not go further in the next step bytesavaible gives some 4,044 bytes, and therefore all dishes are made from the second turn, do-while loop. Previously, I managed to write a version without SSL (which is, however, I needed) and everything worked perfectly as I wanted to send no matter whether large or small files and in different quantities. Servera1 without ssl code:
(removed)

server2/client without SSL:
(removed)

I've changed in server2 signal readyRead to encrypted in connect, becouse it was my mistake, but after that I can't get out from first loop becouse bytesAvailable gives 0 bytes and I don't know. Thanks for the help in advance.

camol
5th March 2011, 15:45
Sorry I can't find the EDIT option to edit my first post:



DServer::DServer(QObject *parent) : QTcpServer(parent)
{
if (!listen(QHostAddress("192.168.56.1"),(quint16)55678))
{
QTextStream(stdout) << errorString();
}
}
void DServer::incomingConnection(int socketDescriptor)
{
serverSocket = new QSslSocket(this);
if (serverSocket->setSocketDescriptor(socketDescriptor))
{
connect(serverSocket, SIGNAL(encrypted()), this, SLOT(response_to_connection()));
connect(serverSocket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(errorOccured(const QList<QSslError> &)));
connect(serverSocket, SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
serverSocket->setProtocol(QSsl::SslV3);
serverSocket->setPrivateKey("server.key");
serverSocket->setLocalCertificate("server.crt");
serverSocket->startServerEncryption();
}
else
{
delete serverSocket;
}
}
void DServer::response_to_connection()
{
QHostAddress connected_host = serverSocket->peerAddress();
if(connected_host.toString() == QString("192.168.56.101"))
{
response_to_replication();
}
}
void DServer::errorOccured(const QList<QSslError> &error)
{
serverSocket->ignoreSslErrors();
}
void DServer::response_to_replication()
{
blockSize = 0;
QByteArray block;
block.clear();
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
serverfiles.clear();
serverfiles = rfilelist();

out << (quint64)0;
out << (out,serverfiles);
out.device()->seek(0);
out << (quint64)(block.size() - sizeof(quint64));

qint64 data = serverSocket->write(block);
QTextStream(stdout) <<"block.size = " <<block.size() <<endl;
QTextStream(stdout) <<"data = " <<data <<endl;

serverSocket->reset();

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

if (blockSize == 0)
{
do
{

if(serverSocket->state() == QAbstractSocket::UnconnectedState)
{
return;
}
serverSocket->waitForReadyRead(1);
}
while(serverSocket->bytesAvailable() < (int)sizeof(quint64));

in >> blockSize;
}

do
{
if(serverSocket->state() == QAbstractSocket::UnconnectedState)
{
return;
}
serverSocket->waitForReadyRead(1);
}
while(serverSocket->bytesAvailable() < blockSize);


QStringList requestedFL;
in >> (in,requestedFL);
serverSocket->reset();

for(int h=0;h<requestedFL.count();h++)
{
QTextStream(stdout) << requestedFL[h] <<endl;
}

if(requestedFL.isEmpty() == false)
{
QByteArray ba;
QByteArray compressed_ba;
int len_requestedFL = requestedFL.count();

for(int i=0; i<len_requestedFL; i++)
{
block.clear();
ba.clear();
compressed_ba.clear();

QFile file(*homepath + requestedFL[i]);
if (!file.open(QIODevice::ReadOnly))
return;
ba = file.readAll();

out << (quint64)0;
out << ba;
out.device()->seek(0);
out << (quint64)(block.size() - sizeof(quint64));

serverSocket->write(block);
serverSocket->reset();

file.close();
blockSize = 0;
int v=0;

do
{
if(serverSocket->state() == QAbstractSocket::UnconnectedState)
{
return;
}
serverSocket->waitForReadyRead(1);
}
while((serverSocket->bytesAvailable() < (int)sizeof(quint64)) );

in >> blockSize;

QString confirmation;
in >> confirmation;
serverSocket->reset();
}
}

}

void DServer::clientDisconnected()
{
if (!serverSocket)
return;

serverSocket->deleteLater();
wtolog(QString("Client Disconnected from Server"));
}

void DServer::response_to_connection()
{
while (hasPendingConnections())
{
QSslSocket *client = nextPendingConnection();

connect(client, SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
serverSockets.append(client);

QHostAddress connected_host = client->peerAddress();
if(connected_host.toString() == QString("192.168.56.101"))
{
response_to_replication(client);
}
}
}


server2client:


Server::Server()
{
clientSocket = new QSslSocket(this);

clientSocket->abort();
QString hostIP("192.168.56.1");
quint16 hostPort = 55678;
connect(clientSocket, SIGNAL(readyRead()),this, SLOT(connectionEstablished()));
connect(clientSocket, SIGNAL(sslErrors(const QList<QSslError> &)),this, SLOT(errorOccured(const QList<QSslError> &)));

clientSocket->setProtocol(QSsl::SslV3);
clientSocket->connectToHostEncrypted(hostIP, hostPort);
}

void Server::connectionEstablished()
{

QSslCertificate cert = clientSocket->peerCertificate();
if(cert.isNull())
{
}

QSslCipher cipher;
cipher = clientSocket->sessionCipher();
initiate_replication();
}


void Server::initiate_replication()
{
QDataStream in(clientSocket);
blockSize = 0;
in.setVersion(QDataStream::Qt_4_0);

if (blockSize == 0)
{
do
{
clientSocket->waitForReadyRead(1);
}
while(clientSocket->bytesAvailable() < (int)sizeof(quint64));

in >> blockSize;
}

do
{
clientSocket->waitForReadyRead(1);
}
while(clientSocket->bytesAvailable() < blockSize);

QStringList receivedFL;
in >> (in,receivedFL);
clientSocket->reset();
QByteArray block;
block.clear();
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);

out << (quint64)0;
out << (out,requestedlist);
out.device()->seek(0);
out << (quint64)(block.size() - sizeof(quint64));

clientSocket->write(block);
clientSocket->reset();


blockSize = 0;
if (blockSize == 0)
{
do
{
clientSocket->waitForReadyRead(1);
}
while(clientSocket->bytesAvailable() < (int)sizeof(quint64));

in >> blockSize;
}

int p=0;
do
{
clientSocket->waitForReadyRead(1000);
}
while (clientSocket->bytesAvailable() < blockSize);

QByteArray compressed_ba;
QByteArray ba;

ba = clientSocket->readAll();
clientSocket->reset();

block.clear();
out << requestedlist[j];
out.device()->seek(0);
out << (quint64)(block.size() - sizeof(quint64));

clientSocket->write(block);
clientSocket->reset();
}

clientSocket->disconnectFromHost();

}

void Server::errorOccured(const QList<QSslError> &error)
{
clientSocket->ignoreSslErrors();

}


Server::~Server()
{
}

wysota
5th March 2011, 16:10
What is this supposed to do?

ba = clientSocket->readAll();
clientSocket->reset();

Instead of using waitForReadyRead() you should really use signals and slots.

camol
5th March 2011, 16:29
When I will get it to work I am going to improve the code in the estetic way but now I really must to get it work.

This element doesn't matter at this moment as I wrote that before without SSL everything work great and like I wanted it to work but now I don't know why i teh first loop I get clientSocket->bytesAvailable = 0 in the first loop in client. The signal encrypted was emitted becouse the program went in the function initiate_replication, the server1 gives the exact amount of bytes that was written in to the socket but at the client side there is nothing to receive that is what bothers me, that why I can't move on with it. Please help.

unit
5th March 2011, 16:51
Let's try code from Secure Socket Client From QT examples. It's work nice.

And also as Mr. Wysota say you should use signal slot mechanism, or use processEvent() in loops

camol
5th March 2011, 16:58
But I tried to use this http://xizhizhu.blogspot.com/2010/08/basic-samples-for-ssl-communication.html
I compiled those codes and they worked fine then I transfered the vital elements to my project and didn't get the positive result like with the original ones.

wysota
5th March 2011, 16:59
When I will get it to work I am going to improve the code in the estetic way but now I really must to get it work.

This element doesn't matter at this moment as I wrote that before without SSL everything work great and like I wanted it to work but now I don't know why i teh first loop I get clientSocket->bytesAvailable = 0 in the first loop in client. The signal encrypted was emitted becouse the program went in the function initiate_replication, the server1 gives the exact amount of bytes that was written in to the socket but at the client side there is nothing to receive that is what bothers me, that why I can't move on with it. Please help.

Your problem is generally the fact that the iodevice has a limited read buffer and your block is larger than it. The approach you are using is generally incorrect, you should be reading the data into your own buffer and only then check the size of your buffer against the size of data you expect.

Either like so:

QByteArray buffer;
while(buffer.size() < blockSize) {
socket->waitForReadyRead();
buffer.append(socket->readAll());
}
doSomethingWith(buffer);

or (better) like so:

QByteArray m_buffer;

void X::onSocketReadyRead(){
m_buffer.append(socket->readAll());
while(m_buffer.size()>=blockSize) processData();
}

camol
5th March 2011, 17:07
I am very greatfull for your help and interest I will give it a try and change my aproach to the problem. Hope it will work, I will response with the results.

EDIT:
But still I have a question why this mechanism which I used in those attachments with "normal" in name works, becouse you wrote that is bad approach but those"normal" verions of my codes work as they should???

camol
6th March 2011, 10:31
Hmm but i think that I do exactly the same you wrote just in a bit diffrent way but idea is the same, firstly the server writes to the socket using QDataStream out, which uses the QByteArray block. Data is written to the block and the the size of the this block is being put at the beginning of the QDataStream. Then at the client side the first do-while loop waits for "the size" of the expected data(for example: files) the size of "the size" is known thats why this is in the first while: clientSocket->bytesAvailable() < (int)sizeof(quint64). After I get the size of the expected incoming data(for example file) thanks to the blockSize now I can wait for my exact data using second do-while loop, and that is why I am using this: clientSocket->bytesAvailable() < blockSize. This is the mechanism that I'm using here and it really worked great, even in sending 10 MB in one file, and as I remember I've used the example from Qt examples and modified it (mostly changed If-instructions to do-while to get to work with big files). After adding SSL something went wrong and it's strange, becouse I read that I can use QSslSockets like QTcpSockets after reimplementing incomingconnection signal. I think that whole handshake stuff is ok becouse I've checked states of both socket server and client side and they were in right state and were encrypted.

wysota
6th March 2011, 12:28
Hmm but i think that I do exactly the same you wrote just in a bit diffrent way but idea is the same, firstly the server writes to the socket using QDataStream out, which uses the QByteArray block. Data is written to the block and the the size of the this block is being put at the beginning of the QDataStream. Then at the client side the first do-while loop waits for "the size" of the expected data(for example: files) the size of "the size" is known thats why this is in the first while: clientSocket->bytesAvailable() < (int)sizeof(quint64). After I get the size of the expected incoming data(for example file) thanks to the blockSize now I can wait for my exact data using second do-while loop, and that is why I am using this: clientSocket->bytesAvailable() < blockSize. This is the mechanism that I'm using here and it really worked great, even in sending 10 MB in one file, and as I remember I've used the example from Qt examples and modified it (mostly changed If-instructions to do-while to get to work with big files). After adding SSL something went wrong and it's strange, becouse I read that I can use QSslSockets like QTcpSockets after reimplementing incomingconnection signal. I think that whole handshake stuff is ok becouse I've checked states of both socket server and client side and they were in right state and were encrypted.

This mechanism is invalid in a general case. Buffers are limited and when they are full, data stops coming in and you'll never reach your desired block count. With plain TCP socket it worked because it had a larger buffer than the SSL socket that apparently has it set at 4kB. Again, this approach is INVALID. I know it has been used in many places in people's code and I think it originates from one of Qt books but it doesn't change the fact that it is invalid and also makes your application prone to DOS attacks.

camol
7th March 2011, 09:52
But still there is one "?" for me becouse I can't get even 20bytes through this socket. The server writes 20bytes(return value of byteswritten) to the socket,it's a test QString message, but I still can't get anything at the client side. The capacity of the SslSocket is so small the? I need to get those first bytes of the socket to be aware of expected amount of date and use your code aproach.

wysota
7th March 2011, 10:31
Is encryption successfully established?

camol
7th March 2011, 13:29
Yes I've checked at both sides isEncrypted and I get true for them.

wysota
7th March 2011, 13:31
And communication works one way or you can't read any data on both ends?

camol
7th March 2011, 13:37
I haven't checked this way client->server yet, becouse my idea was this way first server->client. I've also checked the return value at server side of bytesWritten(sth. like that) was the same as block.size, so I it looks like the data were written to the using socket but the client doesn't receive anything.

wysota
7th March 2011, 13:53
How do you check that you receive no data?

camol
7th March 2011, 13:56
I use socket->bytesAvailable I get 0 all the time. Now ,as I sad, I try to send small amount of date(test QString) that has about 20bytes so I think it shouldn't be too much, but still I'm at the same point when I was trying to send the exact date before.

wysota
7th March 2011, 14:23
I use socket->bytesAvailable I get 0 all the time.
Ok, but WHEN do you do that?

camol
7th March 2011, 14:31
Here


void Server::initiate_replication()
{
QDataStream in(clientSocket);
blockSize = 0;
in.setVersion(QDataStream::Qt_4_0);

if (blockSize == 0)
{
do
{
qDebug << clientSocket->bytesAvailable();
clientSocket->waitForReadyRead(1);
}
while(clientSocket->bytesAvailable() < (int)sizeof(quint64));

in >> blockSize;
}

after the signal encrypted is emitted.

wysota
7th March 2011, 16:09
I'd say that's way too early. Anyway I suggest you rewrite your code to use signals and slots. You wouldn't have any of those problems then.

camol
7th March 2011, 22:26
Now I see the point and I am slowly moving to the idea you presented. But I have a problem constructing the while loop which is suppose to get the size of the next incoming data I tried this but I know that fails:


QByteArray buffer;

void Server::onreadyRead()
{
while(buffer.size() < (int)sizeof(quint64))
{
clientSocket->waitForReadyRead(1);
blockSizee.append(clientSocket->readAll());
}
}

TEST:
The byte size of the "size information", sended by server, is about 8kB but after first readyRead signal client gets first 4kB, and after second signal buffer meets the while condition and skips it, and I can't get the full right size.

wysota
7th March 2011, 23:12
You don't need such while loops.


void Server::onReadyRead(){
buffer.append(socket->readAll());
while(buffer.size() >=4) {
uint32 blockSize = buffer.at(0) << 24 | buffer.at(1) << 16 | buffer.at(2) << 8 | buffer.at(3); // or similar, e.g. qFromBigEndian
if(buffer.size()>=4+blockSize){
QByteArray data = buffer.mid(4,blockSize);
buffer = buffer.mid(4+blockSize);
processData(data);
} else return;
}
}

camol
8th March 2011, 09:51
You don't need such while loops.


void Server::onReadyRead(){
buffer.append(socket->readAll());
while(buffer.size() >=4) {
uint32 blockSize = buffer.at(0) << 24 | buffer.at(1) << 16 | buffer.at(2) << 8 | buffer.at(3); // or similar, e.g. qFromBigEndian
if(buffer.size()>=4+blockSize){
QByteArray data = buffer.mid(4,blockSize);
buffer = buffer.mid(4+blockSize);
processData(data);
}
}
}

why you use while(buffer.size() >=4)? I mean for what "4" stands here for?

wysota
8th March 2011, 11:31
4 stands for sizeof(quint32).

Actually my code had a bug, it was missing an "else" statement. I just corrected it.

camol
10th March 2011, 08:19
void Server::onReadyRead()
{
if(data == Size_of_Data)
{
QTextStream(stdout) << " Entering the slot = "<<a++ <<endl;
buffer.append(clientSocket->readAll());
while(buffer.size() >=4)
{
QTextStream(stdout) << " in while = "<<b++ <<endl;
quint32 blockSize = buffer.at(0) << 24 | buffer.at(1) << 16 | buffer.at(2) << 8 | buffer.at(3); // or similar, e.g. qFromBigEndian

QTextStream(stdout) << " before IF buffer = "<<buffer.size() <<endl;
QTextStream(stdout) << " before IF blockSize = "<<sizeof(blockSize)<<endl;

if(buffer.size()>=4+blockSize)
{
QTextStream(stdout) << " entering IF = "<<c++ <<endl;
QByteArray data = buffer.mid(4,blockSize);
buffer = buffer.mid(4+blockSize);
QTextStream(stdout) << " in IF data = "<<data.size() <<endl;
QTextStream(stdout) << " in IF buffer = "<<buffer.size() <<endl;
//processData(data);
}
else
{
QTextStream(stdout) << " on output buffer.size = "<<buffer.size() <<endl;
return;
}
}
}

else if(data == Exact_Data)
{
QTextStream(stdout) << "getting the right data"<<endl;
}
}


I wrote sth like this, but i don't know exactle when I should pull out the right buffer.size out of the slot (to use it for expecting the incomimg file data)becouse, I've run a simple test and got:



Entering the slot = 0
in while = 0
before IF buffer = 4096
before IF blockSize = 4
entering IF = 0
in IF data = 0
in IF buffer = 4092
in while = 1
before IF buffer = 4092
before IF blockSize = 4
on output buffer.size = 4092
Entering the slot = 1
in while = 2
before IF buffer = 8188
before IF blockSize = 4
on output buffer.size = 8188
Entering the slot = 2
in while = 3
before IF buffer = 8848
before IF blockSize = 4
on output buffer.size = 8848

wysota
10th March 2011, 09:35
Lines #3 and #18 suggest you have two variables called "data" where one shadows the other. What's the purpose of if in #3 anyway?

camol
10th March 2011, 10:33
But one is global the first one and the second one is local for the method, I've changed the first "data" to in_data but it doesn't has any influence. The in_data is an enum type, which I've created, becouse I thought slot onReadyRead always starts after signal readyRead so in_data informs that the incoming data is no longer the size of the file, but exactly the expected file.

EDIT:
When I'm sending a bigger file and I try get the size of it, the result of my test is a bit different:


Entering the slot = 0
in while = 0
before IF buffer = 4096
before IF blockSize = 4
entering IF = 0
in IF data = 0
in IF buffer = 4092
in while = 1
before IF buffer = 4092
before IF blockSize = 4
on output buffer.size = 4092
Entering the slot = 1
in while = 2
before IF buffer = 8188
before IF blockSize = 4
on output buffer.size = 8188
Entering the slot = 2
in while = 3
before IF buffer = 12284
before IF blockSize = 4
on output buffer.size = 12284
Entering the slot = 3
in while = 4
before IF buffer = 16380
before IF blockSize = 4
on output buffer.size = 16380
Entering the slot = 4
in while = 5
before IF buffer = 17688
before IF blockSize = 4
entering IF = 1
in IF data = 17684
in IF buffer = 0

Becouse my "test" ends in IF instruction now.

Another EDIT:
I've changed "4" in your code to "8" and now it stands for quint64 and everything looks like in the first example.

wysota
10th March 2011, 10:57
I still don't understand what the if is for. Anyway, sizeof(blockSize) will always return 4 (it's a 32 bit integer, after all) so I don't understand why you're checking it. Just to make sure - does the sending side encode the block size the same way the receiving size decodes it?

camol
10th March 2011, 11:13
I'm sending it like this:



void DServer::response_to_replication()
{
QTextStream(stdout) << "wszedlem do RESPONSE_TO_REPLICATION" <<endl;

/************************************************** ******************/
/*SENDING LIST WITH STORED FILES TO SERVER WHICH ESTABLISHED CONNECTION*/
/************************************************** ******************/

blockSize = 0;
QByteArray block;
block.clear();
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_6);
serverfiles.clear();
serverfiles = rfilelist();


out << (quint64)0;
out << (out,serverfiles);

out.device()->seek(0);
out << (quint64)(block.size() - sizeof(quint64));
}


the IF-thing: becouse date are coming to the client and when they are ready to read at client side the signal readyRead is emitted which is connected to one single slot called onReadyRead, so when I get the incoming data and interpretate them as the information about the size which was sent by server side of the connection. The signal readyRead will be still emited becouse now client will be receiving the exact data, and the onReadyRead slot will be triggered, so I want to prevent by using this IF-thing to prevent this slot from behaving as it is receiving size when it is already receving the exact expected data.

wysota
10th March 2011, 11:25
I'm sending it like this:
This won't work, obviously. The receiving end expects something completely different.



the IF-thing: becouse date are coming to the client and when they are ready to read at client side the signal readyRead is emitted which is connected to one single slot called onReadyRead, so when I get the incoming data and interpretate them as the information about the size which was sent by server side of the connection. The signal readyRead will be still emited becouse now client will be receiving the exact data, and the onReadyRead slot will be triggered, so I want to prevent by using this IF-thing to prevent this slot from behaving as it is receiving size when it is already receving the exact expected data.
Why do you want to prevent it? I think you don't understand the code I gave you. The slot is meant to fire each time new data arrives into the socket. Without any exceptions or special conditions. Otherwise you'll just lifelock your application.

camol
10th March 2011, 12:07
But you wrote sth like this :



Either like so:

QByteArray buffer;
while(buffer.size() < blockSize) {
socket->waitForReadyRead();
buffer.append(socket->readAll());
}
doSomethingWith(buffer);
[/code]

and I thought that this refers to receiving exact data data, and this blockSize I will get by this last code which I've posted thanks to you.

wysota
10th March 2011, 12:10
I don't see how this code snippet is related to what I have just said :)

camol
10th March 2011, 12:27
:o sorry for noobing, but after what I've read and like you so my first code which worked with QTcpSocket(examples from Qt), I understand it in this way:
1.server is sending data and also at the begining of them server sends the size of data that were written to the socket
2. At the other side client is waiting for data but firstly gets the size, and then knows when to stop receiving the data.

It looked pretty like this in the examples and I've modified them for my needs. But now I see it isn't the right way when I use SSL however I can't understand it in 100% now, however I'm convinced that is a better method and more Qt-like, that it is why it is so important for me.

wysota
10th March 2011, 12:33
Please make sure you understand the code I gave before using it. And never use code you do not understand.

camol
10th March 2011, 12:55
Please tell me before I will study hard your code, what do you mean by this line

processData(data) (I can't figure out when I should pull out the data I need and for example write the in to the file)

becouse I don't know how to refer to it, and maybe are there any signals I should take a closer look?

wysota
10th March 2011, 13:13
processData() is a stub for your method for manipulating the data, the core of the server functionality. I don't know what your program is meant to do so I can't tell you what should be there.

camol
10th March 2011, 13:27
basically I am sending files. The server after establishing connection is sending many many files one by one.

wysota
10th March 2011, 14:13
So probably processData() should store the data on the disk or somewhere else.

camol
10th March 2011, 14:29
But I have noticed that processData() is in if-condition, and as you can see from my "tests" the program is in that if-condition (you wrote) only once (at the first enter to the slot) and at that time data.size is 0.

wysota
10th March 2011, 14:34
Did you adjust the sending side to the semantics of the receiving side or the other way round?

camol
11th March 2011, 07:39
It won't be enough if I just do sth like this?:


QDataStream out(&block, QIODevice::WriteOnly);
//serverfiles is a QStringList
out << (out,serverfiles);
serverSocket->write(block);


This code is in slot which starts thx to encrypted signal.

wysota
11th March 2011, 08:29
No, not really. You are streaming in a QStringList and reading back 4 bytes assembled into integer and an anonymous block of data. How do you expect it to work?

camol
11th March 2011, 09:07
Becouse I still can't see how it should work this, I don't understand how to adjust the code at the server side(I am sending QSringList which has paths for the client becouse every file which will be received by client should be stored with one path from the received list). I still can't get a rid of this way of thinking about the problem, which was presented in the first post. I wrote it and understand it perfectlly. I still see it like this:

-server sends size of "thing" that will be sended in a second
-client receives size of "thing"(client know that firstly it will get the size)
-server sends the "thing"
-client knows that the "thing" will be now received and thx to the size(that it has just received), client knows how big the "thing" will be.

wysota
11th March 2011, 09:17
Maybe you see it like this but you didn't implement it like this.

-server sends size of "thing" that will be sended in a second
-server sends the "thing"



QDataStream out(&block, QIODevice::WriteOnly);
//serverfiles is a QStringList
out << (out,serverfiles);
serverSocket->write(block);

Doesn't seem equivalent to me.

camol
11th March 2011, 09:33
ups it should look like this


out << (out, serverfiles.size());
serverSocket->write(block);
block.clear();
out << (out, serverfiles);
serverSocket->write(block);
block.clear();


This:


out << (out, serverfiles);

I've also found it in Qt Assistant-as a way of sending QtStringList in right way.

Generally as you can see when client connects to the server it always looks like this;
server sends QStringList
client sends his QStringList
server sends files

That is way my first code wasn't random in its simple construction.

wysota
11th March 2011, 09:41
Well, the reading side is still different.

camol
11th March 2011, 11:50
Could you show me how the sending side should look like(I can't figure it out)-will it be universal for sending variables such as QStringList and files?

wysota
11th March 2011, 11:57
The point is the same protocol needs to be used on both sides. If I talk to you in Roman Latin and you only understand Polish there is just no way we will understand each other even if we talk about the same things. Both sides need to communicate in the same "language" or at least they have to agree first on languages they understand. If you're using QDataStream on the transmiting side, the receiver has to use QDataStream as well.

camol
11th March 2011, 12:31
I still don't understand why waitforReadyRead doesn't work in slot here with SSL slot, as far as I am concerned when I use it in slot that was onced triggered, for example:



while(serverSocket->bytesAvailable() == 0)
{
QTextStream(stdout) <<"Waiting for confirmation" <<endl;
}

it should make the program to stop and do the while loop until the readyRead signal is emitted and then the program continue its work. It is very strange that the signal doesn't show up here. At the client side I just did clientSocket->write("Confirmation") and it returned 12 bytes written to the socket, but at the server side still nothing. WaitforReadyRead isn't working as it should? And by the way I am from Poland so I could also understand You ;)

wysota
11th March 2011, 12:40
I still don't understand why waitforReadyRead doesn't work in slot here with SSL slot
Ok, enough for me. I already told you why this happens in the very beginning. I'm not going to repeat myself.

camol
17th March 2011, 12:49
I think I've finally got it, sorry Wysota for me childish behaviour. I have one question is possible some how to check what kind of data type the QByteArray buffer is carring? I am expecting three types: QStringList, QString,, and the exact date which i will write to the file? I tried using QByteArray::contains("STORAGE"), becouse I know that if it will be QStringList, each QString in that QStringList will have "STORAGE" somewhere. But this is not actually working.

EDIT: when in do contains("S") it sees the single char but only one at time.

wysota
18th March 2011, 06:43
I have one question is possible some how to check what kind of data type the QByteArray buffer is carring? I am expecting three types: QStringList, QString,, and the exact date which i will write to the file?
The data is an opaque blob as far as tcp is concerned. You might have one byte of data or one gigabyte of data there. The only way to detect what data is inside is if you inject such information when sending the data and then you perform a scan to detect such marks on the receiving end.

camol
18th March 2011, 09:14
I thought that it would be as easy as I thought. However, for example if I put some mark at the beginning of the QByteArray which I am sending at the server side, when I get it using client:do I have to cut off the "mark" from the beginning, becouse it will affect for example the file which I will create using this received QByteArray and the file won't be the same as the file from the server side?

wysota
18th March 2011, 12:51
You can do whatever you want. The important part is to do the same (or rather "matching") things on both ends of the wire. If you add something to the stream while sending then you have to remove it while receiving.

camol
18th March 2011, 13:09
Big thanks

camol
24th March 2011, 14:01
I've encountered a strange problem. I've rewritten my app in the signal-slot way, and everything works like a charm but only at the first time. The server side is louched the client connects, and my outputs from server and client are showing that everytning works like it should but when I connect to the lounched server with client once more, the server some how is sending each files about 2 times, but I can't figure why. I made many new signals for example send_f() which is emitted only when server gets confirmation from client. But as I said after second client louching it looks like this signal is emited twice but it should be impossible considering that first louchning is always perfect. When I fire the client for third time the connection isn't even established.

EDIT:
SOLVED, I was connecting this signal in wrong place. THX WYSOTA for quick reply :)

wysota
24th March 2011, 14:32
Most probably you are performing two connect() calls instead of one. Or you have some stale data somewhere in some list.