2016-08-30 6 views
0

Also schreibe ich einen Windows Chat und zu Testzwecken sendet mein Client-Programm eine "Hallo" Nachricht an den Server alle 300 ms.C++ Winsock2 Recv Müll

ersten paar Nachrichten kommen gut, aber dann wie ohne Grund beginnen sie junk- screenshot

Offensichtlich werde ich es reparieren wollen und ich suche für Ihre Hilfe :) Hier ist mein Code:

Send-Funktion:

bool Target::Send(char *message) 
{ 
    int length = strlen(message); 
    int result = send(this->ccSock, (char*)&length, sizeof(int), 0); 
    if (result <= 0) 
     return false; 

    Sleep(10); 

    result = send(this->ccSock, message, length, 0); 
    return ((result > 0) ? true : false); 
} 

Empfangsfunktion:

Message Server::Receive(SOCKET socket) 
{ 
    int length = 0; 
    int result = recv(socket, (char*)&length, sizeof(int), 0); 

    Sleep(10); 

    char *rcvData = new char[length]; 
    result = recv(socket, rcvData, length, 0); 

    return { rcvData, result }; 
} 

Nachricht struct:

struct Message { 
    char *msg; 
    int size; 
}; 

Haupt senden Code:

while (true) 
{ 
    if (!target->Send("hello")) 
    { 
     cout << "Connection broken\n"; 
     target->Clean(); 
     break; 
    } 

    Sleep(300); 
} 

Haupt erhalten Code:

while (target.sock) 
{ 
    Message message = server->Receive(target.sock); 
    if (message.size > 0) 
     cout << message.msg << " (" << message.size << ")\n"; 
    else 
    { 
     cout << "Target disconnected\n"; 
     server->Clean(); 
     break; 
    } 

    Sleep(1); 
} 

Ich würde Ihre Hilfe sehr schätzen und erklären, warum dies geschieht!

+2

TL; DR; Haben Sie sich um die ordnungsgemäße Beendigung Ihres Recv-Puffers gekümmert? –

+1

'(Ergebnis> 0)? Wahr: Falsch ist äquivalent zu Ergebnis> 0. – molbdnilo

+0

oh .. wusste nicht, dass nach 2 Jahren Programmierung – daavid245

Antwort

3

Ihr Puffer ist nicht null-terminiert. Wenn Sie also versuchen, es mit std::cout Pufferüberlauf zu drucken, tritt auf. Die richtige Version sollte erhalten Code sein:

char *rcvData = new char[length+1]; 
result = recv(socket, rcvData, length, 0); 
rcvData[length] = '\0'; 

Sie auch nie frei zugewiesenen Speicherpuffer, so dass Ihr Code lecken es auf jeden Receive Anruf.

+0

Vielen Dank, es funktioniert :) Ich habe auch 'memset (rcvData, 0, sizeof (char) * (Länge + 1));' nach dem 'neuen char [] 'Zeile – daavid245

+0

Die' memset() 'ist Overkill, Sie brauchen es überhaupt nicht. Und Sie müssen den Puffer nicht null-terminieren, wenn Sie 'std :: setw()' verwenden, um 'std :: cout' die maximale Anzahl der auszugebenden Zeichen mitzuteilen:' std :: cout << std :: setw (message.size) << message.msg; 'Allerdings würde ich vorschlagen, die Daten in einer' std :: string' statt einer 'char []' zu speichern, die sich um das Ausgabeproblem und das Speicherverwaltungsproblem kümmern würde . –