windows - QT QTcpServer telnet tager tegn \ r \ n

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg skriver QTcpServer. Jeg brugte telnet.exe som klient til test. Ved en ny klientforbindelse sender min server en Hi! besked til klienten, som vises - alt er godt og fint indtil nu.


Men når jeg skriver noget i vinduet telnet.exe, sendes en readyRead() til hvert tegn . Jeg vil kun have det sendt efter ! Hvad er problemet? Er det karakteren af ​​telnet.exe i Windows? Fordi jeg har brugt telnet på min Linux-boks, og det kun sender strengen efter som forventet.

Bedste reference


Desværre er det sådan, at Windows Telnet.exe klienten fungerer, og der er ingen måde at ændre det på.


Du må ikke stole på klientspecifik adfærd som denne, når du håndterer TCP-streams. TCP gør ikke garanti for meddelelsesgrænser, men det garanterer, at dataene leveres ud fra samme synsvinkel, som det er skrevet af klienten. Du skal tage højde for dette ved udformningen af ​​din protokol.


Du skal buffer indgående data og håndtere dette på applikationsprotokollniveau. Almindelige løsninger omfatter at definere en meddelelsesterminator-sekvens (og en mekanisme til at undslippe den pågældende rækkefølge, hvis den kan vises inden for de normale meddelelser) - for eksempel \ r \ n kan være terminator-sekvensen i dette scenario - eller du kan pakke sendede data, der prefixer den med opfølgningsmeddelelsens længde, eller du kan bruge dedikerede meddelelsesbiblioteker (f.eks. ZeroMQ eller ActiveMQ - men så kan du ikke bruge Qt netværk, desværre) osv. [17] [18]

Andre referencer 1


I stedet for at skrive din besked skal du trykke på CTRL + ]] , og skriv derefter send YOURMESSAGE

Andre referencer 2


Ja, der er nogle forskelle mellem Windows og Linux med CR LF, det er 'normal'.


En tilgang, der virker rart, er at gøre brug af buffer og derefter vente på, at dine data er klar eller timeout. For eksempel kan din seperator token være '\ r', og hvis du får en '\ n' efter bare at slippe den.


Her er et eksempel, der forventer et token fra en brugerdefineret protokol :


int Connection::readDataIntoBuffer(int maxSize)
 {
     if (maxSize > MaxBufferSize)
         return 0;

     int numBytesBeforeRead = buffer.size();
     if (numBytesBeforeRead == MaxBufferSize) {
         abort();
         return 0;
     }

     while (bytesAvailable() > 0 && buffer.size() < maxSize) {
         buffer.append(read(1));
         if (buffer.endsWith(SeparatorToken))
             break;
     }
     return buffer.size() - numBytesBeforeRead;
 }


Se http://doc.qt.nokia.com/stable/network-network-chat-connection-cpp.html[19]


Afhængigt af hvad du har brug for et andet forslag er at prøve en pind til nogle standardprotokol . Ligesom dette kan du teste med forskellige typer klienter.


Hvis du vil holde fast ved din brugerdefinerede protokol, foreslår jeg at du skriver din egen klient og skriver ordentlige test sager for at samarbejde med din server. Qt gør det nemt og hurtigt;) Se på netværkseksemplerne.





Du kan overveje readline() i stedet for read() på din QTcpSocket, som er en QIODevice. Det venter på en newline i stedet for at læse () (se doc uddrag nedenfor). Men dette giver mindre kontrol over, hvornår du skal afslutte din linje:


qint64 QIODevice::readLine ( char * data, qint64 maxSize )


Fra doc:



  Data læses til en af ​​de
  Følgende betingelser er opfyldt:

  
  

      
  • Det første '\ n' tegn læses.

  •   
  • maxSize - 1 bytes læses.

  •   
  • Enden af ​​enhedens data registreres.

  •   



Den hemmelige ingrediens i Qt er asynkron signaldrevet design . Se afsnittet Networking/State Machines sektionen i artiklen Threads, Events og QObjects for nogle ideer. [20]