Frage

Ich habe Probleme beim Vergleichen von Zeichenfolgen in C (mit dem ich bin ziemlich neu in). Ich habe Buchse auf dieser Server-Anwendung wartet Daten von einem Client zu akzeptieren. In diesem speziellen Teil meines Programms möchte ich in der Lage sein, eine MySQL-Abfrage auf die vom Client empfangenen Daten basierend auszuführen. Ich möchte in die Lage sein zu wissen, wann die empfangenen Daten den Wert von „newuser“ haben ein einfaches Registrierungsverfahren einzuleiten. Strcmp einen positiven Wert 1 zurückkehrt, wo ich glaube, dass ich eine 0 immer werden sollte, weil die Werte gleich sein sollte.

Source Code:

//setup socket
//loop and select structure to handle multiple connections

if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
// got error or connection closed by client
    if (nbytes == 0) {
        // connection closed
        printf("selectserver: socket %d hung up\n", i);
    } else {
        perror("recv");
    }
    close(i); // bye!
    FD_CLR(i, &master); // remove from master set
} else {

    char check[] = "newuser";
    char fromUser[sizeof check];

    strncpy(fromUser,buf, sizeof check);
    printf("length of fromUser: %d\n", sizeof fromUser);
    printf("length of check: %d\n", sizeof check);
    printf("message from user: %s\n", fromUser);
    printf("check = %s \n", check);
    int diff = strcmp(fromUser, check);
    printf("compare fromUser to check: %d\n", diff);
    if ( strcmp(fromUser, check) == 0) {
        printf("aha! new user");
    }

Ausgabe:

length of fromUser: 8
length of check: 8
newuser from user: newuser
check = newuser 
compare fromUser to check:

Ich habe das Gefühl, ich bin nicht richtig den eingehenden Puffer Handhabung oder fälschlicherweise die Puffer kopiert werden.

War es hilfreich?

Lösung

strncpy Kopien höchstens - in diesem Fall - sizeof Prüfbytes. Wenn das nul Byte nicht in diesem Bereich ist, wird sie nicht kopiert. Sie sind wahrscheinlich immer das Wort „newuser“ als Teil eines längeren Satz, wie „newuser bla bla“, so dass Sie Platz benötigen, die sich Nul

strncpy(fromUser, buf, sizeof check);
fromUser[sizeof check - 1] = '\0';

oder verwenden strlcpy, falls verfügbar.

Andere Tipps

Hier ist der Beispielcode Sie in Ihrer Frage gab (mit Debug-Code entfernt):

//setup socket
//loop and select structure to handle multiple connections

if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
    [... exception handling here ...]
} else {
    char check[] = "newuser";
    char fromUser[sizeof check];

    strncpy(fromUser,buf, sizeof check);
    if ( strcmp(fromUser, check) == 0) {
        printf("aha! new user");
    }

Dieser Code ist falsch; Sie kopieren möglicherweise mehr Bytes von buf [] als empfangen wurden. Dies führt zu Ihnen gegen Müll zu vergleichen (das könnte geschehen zufällig Ihre „newuser“ string übereinstimmen). Und wie andere Leute schon gesagt haben, haben Sie einen zweiten Fehler aufgrund nicht NUL eines Ihrer Strings beendet wird.

In diesem Fall würde ich memcmp () verwenden. Das ist wie strcmp (), aber es braucht vielmehr einen Längenparameter als NUL-terminierten Strings erwartet.

//setup socket
//loop and select structure to handle multiple connections

if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
    [... exception handling here ...]
} else {
    static const char check[] = "newuser";
    const size_t check_len = sizeof(check) - 1; // exclude the NUL terminator
    if (nbytes >= check_len && memcmp(buf, check, check_len) == 0) {
        printf("aha! new user");
    }

P. S. Nicht direkt, sondern recv () kann scheitern -1 Rückkehr mit errno==EINTR. Dies ist nicht ein Fehler, die Sie gerade wieder versuchen müssen. Normalerweise, so dies geschieht selten, dass weg, ohne die Menschen bekommen es überprüft, bis sie mit einem anderen Code zu integrieren, die Signale verwendet, und plötzlich ihr Code nicht zufällig.

In einer select()-basierten Anwendung, sollten Sie auch Ihre Sockets nicht blockierend werden Einstellung und dann für errno==EAGAIN überprüfen, und in diesem Fall den select() zurück. Dies kann passieren, wenn die TCP / IP-Stack ein beschädigtes Paket empfängt - es denkt, dass es ein Paket hat so select() werden Ihnen sagen, es ist lesbar, es ist nur, wenn Sie versuchen, es zu lesen, dass die TCP / IP-Stack funktioniert die Berechnung der Prüfsumme und realisiert hat werfen die Daten weg. Es wird dann entweder Block (sehr schlecht), oder wenn es nicht blockierend gesetzt ist, dann wird es -1 mit errno==EAGAIN zurück.

Ich glaube, das Problem hier (eines der Probleme hier) ist, dass fromuser (aufgrund der Art und Weise ihr erstellt wird) beendet ist nicht null.

Sie vermissen '\ 0' Zeichen am Ende fromuser:

...
strncpy(fromUser,buf, sizeof check);
fromUser[strlen(check)] = '\0';

Zwei Änderungen erforderlich:

char fromUser[sizeof check] = {'\0'}; //Make all null characters
strncpy(fromUser,buf, sizeof check -1); //Last character is for null character.

Dieser Code scheint aus:

if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) 
{
 // your stuff
} 
else {
const char *pCheck = "newuser";
char *fromUser = new char[nbytes];
strncpy(fromUser, buff, nbytes);
fromUser[nbytes] = '\0';
if(strcmp(fromUser,check)==0)
 // blah

delete [] fromUser;
}

Ersetzen mit:

char check[] = "newuser\0";
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top