recv kasuje zmienne lokalne?

0

No więc jestem już na ukończeniu moich aplikacji serwera i klienta w winsocku. Został właściwie tylko jeden mały problem... Ale jest on jednym z najdziwniejszych z jakimi się dotąd spotkałem...

 
//ExampleServer.cpp

...

DWORD WINAPI ReceiverThread(LPVOID ClientSocketDeskryptor) //wątek do odbierania wiadomości serwera
{
    char message[200];
    int CSD = *(reinterpret_cast<int*>(ClientSocketDeskryptor)); //przechowuje deskryptor gniazda
    int i=100;//zmienna dodatkowa do debuggowania
    char a = 'a'; //zmienna dodatkowa
    int numbytes;
    while(1)
    {
        memset(message,'\0',200);
        cout<<"CSD= "<<CSD<<endl;
        numbytes=recv(CSD,message,220,0); //[BREAKPOINT 1]

        if(numbytes==0)//[BREAKPOINT 2]
        {
            break;
        }
        if(numbytes==-1)
        {
            cout<<"Error receiving message error nr "<<WSAGetLastError()<<endl;
            continue;
        }

        if(message[0]=='\0')
        {
            continue;
        }
        cout<<message<<endl;
        cin.ignore();
    }
    cout<<"Receiver exiting..."<<endl;
}

...

Powyższa funkcja to oddzielny wątek do obsługiwania odpowiedzi serwera. W ten sposób mogę jednocześnie pisać i odbierać wiadomości.

Niestety, wątek działa tylko podczas odbierania pierwszej wiadomości. Za każdym następnym razem w konsoli nie pojawia się nic. Wątek nie zakończył pracy, po prostu zawiesił się na pętli while(1) gdyż...no właśnie.

Spójrzcie na wyniki debugowania. Podglądałem zmienne CSD,i,a oraz numbytes.
[BREAKPOINT 1] (przed recv())
CSD=220
i=100
a='a'(97 ASCII)

[BREAKPOINT 2] (po recv())
CSD=1998210272 (różnie,generalnie śmieci)
i=0;
a=null(0 ASCII)

Nic dziwnego że za 2 razem nie działa skoro CSD to śmieci.Przekazanie tego do recv() zwraca -1 i funkcja blokuje się na pętli while()

No więc, ja nie mam pojęcia. Od wielu godzin siedzę i rozmyślam. Ale jakoś żadne wytłumaczenie mi do głowy nie przychodzi.Nigdy nie widziałem podobnego zjawiska. Ktokolwiek wpadnie na rozwiązanie dla mnie jest bogiem programowania!

6
char message[200];
numbytes=recv(CSD,message,220,0);

Nie przeszkadza Ci, że bufor ma 200 bajtów a każesz do niego zapisać nawet 220? To jest undefined behavior jeżeli funkcja recv zapisze więcej niż 200 bajtów. I to zapewne się dzieje.

https://en.wikipedia.org/wiki/Buffer_overflow

0

witaj w krainie języka c++ gdzie mały błąd w jednym miejscu może wprowadzić błąd w całkiem innym miejscu aplikacji
ogólnie mazanie losowymi danymi po losowych miejscach pamięci to średni pomysł, nie ma tu żadnej kontroli, musisz się samemu pilnować

2

No jak zrobisz bufor na 200 znaków a wczytasz 220 to się nie dziw że może się okazać że 20 bajtów na stosie obok twojego bufora zostało zamazane ;)

0
Endrju napisał(a):
char message[200];
numbytes=recv(CSD,message,220,0);

Nie przeszkadza Ci, że bufor ma 200 bajtów a każesz do niego zapisać nawet 220? To jest undefined behavior jeżeli funkcja recv zapisze więcej niż 200 bajtów. I to zapewne się dzieje.

https://en.wikipedia.org/wiki/Buffer_overflow

pff faktycznie tego nie zauważyłem. Zamiast 200 mam tam 220, literówka się wkradła.A BO tłumaczy, dlaczego pozostałe zmienne są kasowane.

No ale bez cb nigdy bym tego nie zauważył, więc dzięki wielkie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1