InternetReadFile daje 0 bajtów przed końcem pliku

Odpowiedz Nowy wątek
2011-08-10 12:15
0

W oparciu o:

The amount of data to be read for each call to InternetReadFile is specified by the dwNumberOfBytesToRead parameter and the data is returned in the lpBuffer parameter. A normal read retrieves the specified dwNumberOfBytesToRead for each call to InternetReadFile until the end of the file is reached. To ensure all data is retrieved, an application must continue to call the InternetReadFile function until the function returns TRUE and the lpdwNumberOfBytesRead parameter equals zero.

Mamy taki kawałek kodu:

            while(InternetReadFile(hRequest, ptr4, WielkoscPamieci-1, &dwBytesRead) != false)
            {
                ptr4 += dwBytesRead;
                if (dwBytesRead == 0)
                {
                    break;
                }
            }
            ptr4 += dwBytesRead;
            *ptr4 = '\0'; 

Z tymże robi mi się tu kaszana, bo niestety, czasem w dwBytesRead pojawia się 0, choć plik się jeszcze nie skończył!
Nie wiem z czego to wynika, czy z kiepskiego łącza może? Może przeciążenie serwera? Nie za każdym razem tak się dzieje.

Tak czy siak, tak być nie może. Sprawdziłam testowo, że jak wyrzucę tego break'a, to niby działa. Jednakże na forach wyczytałam, że ludzie mają odwrotny problem - brak breaka powoduje problemy przy pobieraniu (z resztą nie zgadza się to z tym, co jest napisane na msdnie). Nie chcę poprawiać kaszany na nową kaszanę. Czy wiecie może, jakie będzie na pewno dobre rozwiązanie?

edytowany 1x, ostatnio: aurel, 2011-08-10 12:16

Pozostało 580 znaków

2011-08-10 13:06
Kumashiro
0

Nie używam tej funkcji, ale w przytoczonej przez Ciebie dokumentacji jest:

an application must continue to call the InternetReadFile function until the function returns TRUE !!!!!!!!!!!!!>>>>>> and <<<<<!!!!!!!!!!!!!!!!! the lpdwNumberOfBytesRead parameter equals zero

(podkreślenie moje).

Pozostało 580 znaków

2011-08-10 13:39
0

Niby racja, ale taka sytuacja nigdy nie występuje, mianowicie kod:

while(true)
{
    if(InternetReadFile(hRequest, ptr4, WielkoscPamieci-1, &dwBytesRead) != true && dwBytesRead == 0)
        break;
 
    ptr4 += dwBytesRead;
}

nie wychodzi z pętli...

EDIT:
Na razie zmieniłam na:

while(InternetReadFile(hRequest, ptr4, WielkoscPamieci-1, &dwBytesRead) != false)
{
        if (dwBytesRead == 0)
            break;
 
    ptr4 += dwBytesRead;
}

....i wygląda jakby pomogło... Widać plik wcale nie był niedokończony, tylko właśnie jakiś nadmiar był dopisywany... Nic to, zobaczy się, czy się powtórzy.

edytowany 2x, ostatnio: aurel, 2011-08-10 13:49

Pozostało 580 znaków

2011-08-10 14:46
Kumashiro
0
aurel napisał(a)

Niby racja, ale taka sytuacja nigdy nie występuje, mianowicie kod:

 
while(true)
{
if(InternetReadFile(hRequest, ptr4, WielkoscPamieci-1, &dwBytesRead) != true && dwBytesRead == 0)
break;
ptr4 += dwBytesRead;

}


> nie wychodzi z pętli...

Ale to jest źle. Dokumentacja: "until the function returns TRUE and the lpdwNumberOfBytesRead parameter equals zero". Zatem z pętli powinnaś wyskoczyć wtedy, gdy InternetReadFile() zwróci TRUE i dwBytesRead będzie równe zero. W Twoim warunku uciekasz z pętli gdy funkcja zwróci FALSE i dwBytesRead jest równe zero.

Czyli, o zakończeniu wczytywania decyduje głównie wartość zwracana przez funkcję, gdyż w przypadku TCP (a po nazwie wnoszę, że z tym protokołem ciągniesz dane) możesz nic nie dostać, pomimo że to jeszcze nie jest koniec transmisji (musisz ponowić). Koniec transmisji jest sygnalizowany wartością TRUE *i* zerową liczbą wczytanych bajtów. Nie wiem co oznacza przypadek, kiedy funkcja zwróci FALSE (w zacytowanym przez Ciebie fragmencie dokumentacji nic na ten temat nie ma).
Dżizas... Przecież to oczywiste. FALSE oznacza, że transmisja trwa... Potrzebuję więcej kawy... - Kumashiro 2011-08-10 14:49

Pozostało 580 znaków

2011-08-10 15:27
0

Wygląda na to, że masz rację! Przeoczyłam :/
Mimo to mój obecny kod (najnowszy zamieszczony) będzie najlepszym rozwiązaniem, ponieważ FALSE nie oznacza wcale, że transmisja trwa:

Returns TRUE if successful, or FALSE otherwise. To get extended error information, call GetLastError.

edytowany 2x, ostatnio: aurel, 2011-08-10 15:28

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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