[Qt-interest] QTcpSocket missing some data

Srikanth Bemineni srikanth.bemineni at gmail.com
Sat Feb 7 15:56:50 CET 2009


Thank you for replying you have answered my question perfectly.I didn't
write this code. It was written by some team member long back I am facing
this problem while adding a new feature. I know most of the code is
irrelevant.Please find the answers below

On Sat, Feb 7, 2009 at 2:50 AM, Thiago Macieira <
thiago.macieira at trolltech.com> wrote:

> 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".


  <SB>This person was using C before so he always sticks to this type of
coding I cannot change him.

>
>
> >
> >    // 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.

 <SB>Yeah will try to change this.


>
>
> 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:
>

 <SB>Its the first Case .This app doesn't have a thread.I also felt the same
that we should not be using any flush

>
> 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 );
>


> <SB>Here are you talking about QTextStream ReadLine.I think QtextStream is
> not derived from QIODevice.It is actually gives me '\n' at the end when I
> call readLine.The next piece of the code, the "if else"conditions has to
> interchanged . I know this problem
>

   There are some place where the code has been coded this way

   writeToServer("xx") while sending it will add '\n' at the end
   writeToServer("xx\n")  it will not try to  add '\n' because of the end
'\n' check
   writeToServer("xx\n\n") it will not try to  add '\n' because of the end
'\n' check but it still contains two '\n\n'<SB>



> 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.

  <SB>You are absolutely correct.But people are reluctant to change any
working piece of code, if it is working for the current condition.


> What is happening is that QTextStream is buffering. It reads in large
> chunks (16 kB), so it probably reads 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).


 <SB> The above point correctly answers my questions, why I am not getting
the second cmd?. I want to change it to   QIODEvice->readLine but only to
keep that coded persons satisfied. I have to use the QTextSTream to not to
bother the tentions. I have changed the code to this format yesterday and
its works pretty fine

    szClientData = ts.readLine();
    while( !szClientData.isEmpty() )
    {

         if( szClientData.endsWith( "\n" ) )
              szClientData = szClientData.left( szClientData.length() - 1
);

         if( szClientData != "" )
        {
           TRACE1( "Emitting clientDataReady signal." );
           emit clientDataReady( szClientData );
        }
        szClientData = ts.readLine();
    }
    In this case if I have '\n\n' I will get an empty cmd some times thats
fine.<SB>

>
>
> 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
>
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at trolltech.com
> http://lists.trolltech.com/mailman/listinfo/qt-interest
>
>


-- 
_/\_
With Regards
SB Angel Warrior
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20090207/be126236/attachment.html 


More information about the Qt-interest-old mailing list