2017-09-09 4 views
0

Ich habe wirklich keine Ahnung, ob dies eine Art Verzögerung des Netzwerks ist, mein PC oder was auch immer, ich bin ziemlich neu in der Socket-Programmierung und wurde versuchen, diese Arbeit für eine Weile zu machen, einen einfachen Rahmen der Umsetzung meiner Arbeit in einem zukünftigen Projekt für meine Klasse zu erleichtern und ich verwende diese Funktionen in dem Problem, das ich habe:recv() nicht alle Daten vom Client mit send()

void TCPSocket::send(const std::string& message, int flags) { 

    if (isListening || !isConnected) { 
     throw ConnectionException("Can't send message from a socket that is not connected"); 
    } 

    int msgLength = message.length(); 
    int bytesLeft = msgLength; 
    int bytesSent; 
    const char* cMessage = message.c_str(); 

    while (bytesSent < msgLength) { 

     const char* cMessageLeft = cMessage + bytesSent; 

     int result = ::send(socketFd, cMessageLeft, bytesLeft, flags); 
     if (result == -1) { 
      throw ConnectionException("Could not send message. Error: " + std::string(strerror(errno))); 
     } 

     bytesLeft -= result; 
     bytesSent += result; 

    } 

} 

std::string TCPSocket::recv(unsigned int maxlen, int flags) { 

    if (isListening || !isConnected) { 
     throw ConnectionException("Can't receive message in a socket that is not connected"); 
    } 

    char buffer[maxlen+1]; 
    int result = ::recv(socketFd, buffer, maxlen, flags); 

    if (result == -1) { 
     throw ConnectionException("Could not receive message. Error: " + std::string(strerror(errno))); 
    } 
    if (result == 0) { 
     isConnected = false; 
     throw ClosedConnection("Client closed connection."); 
    } 
    buffer[result] = '\0'; 
    std::string message(buffer); 

    return message; 

} 

Es funktioniert großartig mit nur einem Nachricht, ich empfange und sende mit verschiedenen ausführbaren Dateien mit überhaupt kein Problem, aber ich habe versucht, mehr als 1 Nachricht zu senden und mein Problem gestartet, manchmal bekomme ich den Server 1 Nachricht zu erhalten, manchmal wird es keine und wenn ich nur eine hinzufügen Wenige printf() s es bekommt sie alle, könnte jemand bitte expl Ain zu mir, warum das passiert?

Code Auftraggeber:

int main() { 
    TCPSocket cl1(0); 

    try { 
     cl1.connect("localhost", 1170); 
     for (int i = 0; i < 5; i++) { 
      //printf("Esperando 5s... "); 
      std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 
      //printf("Pronto!\n\n"); 

      cl1.send("Thank you!\n"); 
      //printf("Msg enviada\n\n"); 

     } 
     cl1.close(); 
    } 
    catch(std::exception &e) { 
     std::cout << e.what() << std::endl; 
    } 
} 

Server Code:

int main() { 
    TCPSocket sv1(0); 

    try { 
     sv1.bind(1170); 
     sv1.listen(); 
     TCPSocket client = sv1.accept(); 
     printf("Cliente conectado\n"); 
     try { 
      for (;;) { 
       //client.send("Welcome !\n"); 
       std::cout << client.recv(256) << std::endl; 
      } 
     } 
     catch (const ClosedConnection & x) { 
      printf("Connection closed\n"); 
     } 

    } 
    catch(std::exception &e) { 
     std::cout << e.what() << std::endl; 
    } 
} 

Wenn ich die printfs auf dem Client-Code Kommentar-, werden alle Daten auf dem Server empfangen.

Klar, ich sende die Nachricht mit einem 5s-Intervall, recv() liest nur die erste und es blockiert, bis client beendet die Ausführung, nie den Rest der Nachrichten lesen, die im Puffer sein sollte. Aus irgendeinem Grund, printfs auf dem Client-Code zu haben, lassen Sie die Anwendungen gut laufen.

+0

Durch Entwurf. TCP ist das Stream-Protokoll, kein Nachrichtenprotokoll. Mit anderen Worten, Sie müssen 'recv' in einer Schleife aufrufen, bis Sie alle Daten erhalten, die Sie erwarten. – selbie

+0

@selbie Ich verstehe das, aber warum bekomme ich "Danke" nur einmal, wenn klar ist, dass ich es 5 Mal gesendet habe und sie sollten im Puffer sein? Wenn ich die 5-mal wirklich schnell sende, dann recv() wird sie alle in die gleiche Zeichenfolge zurückgeben, aber das ist nicht, was passiert. –

+0

poste bitte ein [mcve] – xaxxon

Antwort

1

Sie scheinen bytesSentbytesSent nicht zu initialisieren, so scheint die Anzahl der Zeiten, die tatsächlich die Daten senden würde, unbestimmt zu sein.

int bytesSent = 0; 
+0

Anscheinend war das wirklich das Problem, ich fühle mich jetzt ziemlich dumm, danke. –

+1

Sich dumm zu fühlen ist gut für dich. Oder zumindest ist es besser für dich, als dich schlau und dumm zu fühlen. – user4581301