4 Attachment(s)
QSslSocket vs QTcpSocket problem
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.
Re: QSslSocket vs QTcpSocket problem
Sorry I can't find the EDIT option to edit my first post:
Code:
{
{
}
}
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()
{
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;
block.clear();
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;
serverSocket->reset();
if (blockSize == 0)
{
do
{
{
return;
}
serverSocket->waitForReadyRead(1);
}
while(serverSocket->bytesAvailable() < (int)sizeof(quint64));
in >> blockSize;
}
do
{
{
return;
}
serverSocket->waitForReadyRead(1);
}
while(serverSocket->bytesAvailable() < blockSize);
in >> (in,requestedFL);
serverSocket->reset();
for(int h=0;h<requestedFL.count();h++)
{
}
if(requestedFL.isEmpty() == false)
{
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
]);
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
{
{
return;
}
serverSocket->waitForReadyRead(1);
}
while((serverSocket->bytesAvailable() < (int)sizeof(quint64)) );
in >> blockSize;
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);
if(connected_host.
toString() == QString("192.168.56.101")) {
response_to_replication(client);
}
}
}
server2client:
Code:
Server::Server()
{
clientSocket = new QSslSocket(this);
clientSocket->abort();
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()
{
blockSize = 0;
if (blockSize == 0)
{
do
{
clientSocket->waitForReadyRead(1);
}
while(clientSocket->bytesAvailable() < (int)sizeof(quint64));
in >> blockSize;
}
do
{
clientSocket->waitForReadyRead(1);
}
while(clientSocket->bytesAvailable() < blockSize);
in >> (in,receivedFL);
clientSocket->reset();
block.clear();
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);
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()
{
}
Re: QSslSocket vs QTcpSocket problem
What is this supposed to do?
Code:
ba = clientSocket->readAll();
clientSocket->reset();
Instead of using waitForReadyRead() you should really use signals and slots.
Re: QSslSocket vs QTcpSocket problem
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.
Re: QSslSocket vs QTcpSocket problem
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
Re: QSslSocket vs QTcpSocket problem
But I tried to use this http://xizhizhu.blogspot.com/2010/08...unication.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.
Re: QSslSocket vs QTcpSocket problem
Quote:
Originally Posted by
camol
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:
Code:
while(buffer.size() < blockSize) {
socket->waitForReadyRead();
buffer.append(socket->readAll());
}
doSomethingWith(buffer);
or (better) like so:
Code:
void X::onSocketReadyRead(){
m_buffer.append(socket->readAll());
while(m_buffer.size()>=blockSize) processData();
}
Re: QSslSocket vs QTcpSocket problem
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???
Re: QSslSocket vs QTcpSocket problem
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.
Re: QSslSocket vs QTcpSocket problem
Quote:
Originally Posted by
camol
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.
Re: QSslSocket vs QTcpSocket problem
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.
Re: QSslSocket vs QTcpSocket problem
Is encryption successfully established?
Re: QSslSocket vs QTcpSocket problem
Yes I've checked at both sides isEncrypted and I get true for them.
Re: QSslSocket vs QTcpSocket problem
And communication works one way or you can't read any data on both ends?
Re: QSslSocket vs QTcpSocket problem
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.
Re: QSslSocket vs QTcpSocket problem
How do you check that you receive no data?
Re: QSslSocket vs QTcpSocket problem
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.
Re: QSslSocket vs QTcpSocket problem
Quote:
Originally Posted by
camol
I use socket->bytesAvailable I get 0 all the time.
Ok, but WHEN do you do that?
Re: QSslSocket vs QTcpSocket problem
Here
Code:
void Server::initiate_replication()
{
blockSize = 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.
Re: QSslSocket vs QTcpSocket problem
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.