[Qt-interest] QTcpSocket missing some data

Thiago Macieira thiago.macieira at trolltech.com
Sat Feb 7 09:50:12 CET 2009


Srikanth Bemineni wrote:
>Hi
>
>I have server and a client program .The client uses QTcpsocket to send
> the data and I Cserver to accept the connections.I have made it event
> based to whenever I receive the data from the client. When I write two
> messages in this case these are commands.I only receive only one. When
> I put in debug I get both the messages.

Hi Srikanth

Comments below:

>writeToServer(QString szTempMsg )
>{
>
>szTempMsg = outputMsg;
>    if( szTempMsg.at( szTempMsg.length() - 1 ) != '\n' )
>        szTempMsg += "\n";

Hint: szTempMsg.endsWith('\n')

Nitpicking: technically, a QString doesn't have to be NUL-terminated, so 
giving it the Polish-notation prefix "sz" is not always correct. A simple 
"s" would be correct, or maybe "qs".

>
>    // Also check that the socket has a connection
>    if (CallerSocket->state() == QTcpSocket::ConnectedState) {
>        if (CallerSocket->write(szTempMsg.toAscii(), szTempMsg.length())
> == -1) {

This line is wrong. When a QString is converted to another encoding, it 
might change length. Please convert it and store it in a QByteArray first, 
then send the byte array.

Also note that QIODevice has an overload that takes a QByteArray.

>             cout<<"Error writing"
>        }
>        CallerSocket->flush();

The flush operation tries to write as many bytes as possible without 
blocking. The fact that you're using it tells me one of two things:

1) you're using this socket in the main thread or in a thread which has an 
event loop, in which case the flushing is unnecessary. As soon as the 
event loop runs again, the bytes will be sent.

2) you're using this socket in an auxiliary thread which has no event 
loop. In that case, you should be calling waitForBytesWritten in a loop, 
verifying that the bytesToWrite() count dropped to 0.

Which one of these cases is it?

>void CBaseManager::slot_ClientSocketInputArrived()
>{
>    QTextStream    ts( clientSocket );
>    QString        szClientData = "";
>
>    HDUTRACE1( "CBaseManager::ClientSocketInputArrived()" );
>
>    while( clientSocket->canReadLine() )
>    {
>        szClientData = ts.readLine();
>
>    // Check if there is a new line or double new line character on the
>input
>    if( szClientData.endsWith( "\n" ) )
>        szClientData = szClientData.left( szClientData.length() - 1 );
>    else if( szClientData.endsWith( "\n\n" ) )
>        szClientData = szClientData.left( szClientData.length() - 2 );

This code looks misleading to me. QIODevice::readLine returns a QString 
that, according to the documentation, has no trailing end-of-line 
characters. So neither of these branches will ever run.

What's more, it would be dead code anyways, even if readLine did return 
more than newlines. Note that, if a string ends in \n\n, it necessarily 
ends in \n too. So the first branch is always taken.

One more thing: szClientData.chop(1);

>    // emit the signal that data from the client has arrived
>    if( szClientData != "" )

Hint: szClientData.isEmpty()

>    {
>        TRACE1( "Emitting clientDataReady signal." );
>        emit clientDataReady( szClientData );
>    }
>  }
>}

I think the problem is the fact that you're using QTextStream so you can 
use its readLine() method. If you were using the QIODevice (QTcpSocket) 
method readLine(), you wouldn't be having this problem.

What is happening is that QTextStream is buffering. It reads in large 
chunks (16 kB), so it probably read from the device all the pending 
messages. But, when it did that, the socket no longer has any pending 
data, so necessarily your call to canReadLine() will fail (the socket 
can't read a line, but the stream can).

The rule of thumb is: when you use a QTextStream on a QIODevice, do not 
use the QIODevice directly.

-- 
Thiago Macieira - thiago.macieira (AT) nokia.com
  Senior Product Manager - Nokia, Qt Software
      Sandakerveien 116, NO-0402 Oslo, Norway
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part.
Url : http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20090207/d0573204/attachment.bin 


More information about the Qt-interest-old mailing list