Socket, pobieranie zawartosci www

problemy z tworzeniem programów do obsługi sieci, internetu, e-mail itp..

Socket, pobieranie zawartosci www

Nowy postprzez shycat » poniedziałek, 15 czerwca 2009, 21:38

Witam, pisze sobie maly programik, ktory pobiera zawartosc strony www... uzywam do tego socketow... program dziala poprawnie, jezeli kod strony jest "maly", natomiast, jezeli kod jest wiekszy, pobierany jest tylko kawalek... do odbierania odpowiedzi od socketu po wczesniejszym polaczeniu uzylam kodu:


void __fastcall TForm1::ClientSocket1Read(TObject *Sender, TCustomWinSocket *Socket)
{
AnsiString odp=Socket->ReceiveText();

....

}
Avatar użytkownika
shycat
Homos antropiczny
Homos antropiczny
 
Posty: 51
Dołączył(a): środa, 20 sierpnia 2008, 12:37
Lokalizacja: Śląsk
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: C++ Builder 2006, Delphi 7
Gadu Gadu: 26712716
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez Miroo_007 » wtorek, 16 czerwca 2009, 00:34

ClientSocket i ServerSocket to przestarzałe kontrolki. Od C++ Builder 2007/Delphi 2005 nie są dołączone do tych środowisk (należy je ręcznie zainstalować). Do pobierania treści strony używa się TIdHTTP. A wygląda to tak:
Kod: Zaznacz cały
//Plik nagłówkowy np. Unit1.cpp
//------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        TStringList *Lista = new TStringList;       
        Lista->Add(HTTP1->Get(Edit1->Text));
}
//------------------------------------------

Co do twojego projektu, to spróbuj coś takiego:
Kod: Zaznacz cały
void __fastcall TForm1::ClientSocket1Read(TObject *Sender, TCustomWinSocket *Socket)
{
       TStringList *Lista = new TStringList;
       Lista->Add(Socket->ReceiveText());
       //....
}

Ten problem był omawiany tutaj.
Avatar użytkownika
Miroo_007
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): sobota, 18 października 2008, 10:49
Lokalizacja: Rzeszów
Podziękował : 0
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez shycat » wtorek, 16 czerwca 2009, 09:13

Witam, wiem dobrze, ze sockety sa stare i wiekszosc ludzi uzywam pakiety Indy, ale ja chce uzyc socketow... rozwiazanie ktore mi podales niestety nie dziala... dalej jest wczytywany tylko pierwszy kawalek... sprawdzilam tez czy wpisanie tego w petle while pomoze... no nie pomoglo, pamietam, ze byl jakis prosty sposob na rozwiazanie tego problemu... ale nie pamietam jaki, eh
Avatar użytkownika
shycat
Homos antropiczny
Homos antropiczny
 
Posty: 51
Dołączył(a): środa, 20 sierpnia 2008, 12:37
Lokalizacja: Śląsk
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: C++ Builder 2006, Delphi 7
Gadu Gadu: 26712716
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez Cyfrowy Baron » wtorek, 16 czerwca 2009, 09:51

Problemem jest zmienna typu AnsiString, która nie przechowuje łańcuchów znaków zawierających znaki w systemie Unicode, dlatego nie ma to związku z rozmiarem strony, lecz z faktem, że po napotkaniu znaku Unicode, reszta jest odrzucana, gdyż nie można jej zapisać w zmiennej typu AnsiString, dlatego niezależnie od tego czy to będą sockety, komponenty Indy, czy też sposoby opisane w serwisie Cyfrowy Baron, nie da się znaków Unicode zapisać w zmiennej AnsiString, gdyż jest to zmienna 8-bitowa. Należy posłużyć się raczej zmienną typu WideString, kóra podobnie jak zmienna AnsiString może pomieścić od 4 bajtów do 2 gigabajtów, ale w odróżnieniu do AnsiString może przechowywać znaki Unicode.
Pojawi się jednak problem z obsługą tych zmiennych, niemniej jednak można dokonać konwersji na AnsiString, o czym było już na tym forum w dziale ogólnym, ale nie pamiętam gdzie.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez shycat » wtorek, 16 czerwca 2009, 10:19

Cyfrowy Baronie, to co mowisz jest jak najbardziej prawda, jednak jestem pewna, ze problem lezy po stronie socketu, ktory strone pobiera "fragmentarycznie" ... czyli np po 1 kb ... i instrukcja:

Socket->ReceiveText();

pobiera wlasnie tylko jeden fragment... zrobilam test... na localhoscie umiescilam sobie prosty skrypt php ktory wyswietla 100'000 razy literę "a"... i tylko ja. Moj program pobral tylko czesc z wszystkich liter... a w tym ciagu nie znajdowaly sie zadne znaki Unicode... sprawdzilam czy wszystko gra w przegladarce - i tak... wszystko jest ok, litera a zostala wyswietlona 100'000 razy...
Avatar użytkownika
shycat
Homos antropiczny
Homos antropiczny
 
Posty: 51
Dołączył(a): środa, 20 sierpnia 2008, 12:37
Lokalizacja: Śląsk
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: C++ Builder 2006, Delphi 7
Gadu Gadu: 26712716
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez polymorphism » wtorek, 16 czerwca 2009, 10:58

Cyfrowy Baron napisał(a):nie da się znaków Unicode zapisać w zmiennej AnsiString, gdyż jest to zmienna 8-bitowa.

AnsiString to klasa, a nie jakaś zmienna 8-bitowa! Typem 8-bitowym to może być typ char, ale nie klasa do przechowywania tekstu. A jeśli już mowa o unikodzie, to nikt nie powiedział, że jest to zawsze utf-16 (natywnie w windows). W protokole HTTP, jeśli chodzi o unikod, najczęściej (o ile nie jedynie) używane jest kodowanie utf-8, z racji oszczędności pamięci i zgodności z kodowaniem ASCII. AnsiString jest w stanie przechować unikod w tym kodowaniu, choć nie jest w stanie w pełni z nim współpracować - indeksowanie, obliczanie długości itd. Może pełnić rolę kontenera i nic więcej.

To tak nawiasem...
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez Witold » wtorek, 16 czerwca 2009, 11:06

shycat napisał(a): natomiast, jezeli kod jest wiekszy, pobierany jest tylko kawalek...


Możesz podać adres jakieś strony, której wczytuje się tylko fragment?
Gdy wywoływane jest zdarzenie ClientSocket1Read dla większej strony i przychodzi jeden z fragmentów, łączysz te fragmenty z sobą ?

np
Kod: Zaznacz cały
void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
      TCustomWinSocket *Socket)
{
Memo1->Lines->Add(Socket->ReceiveText());
}
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez Cyfrowy Baron » wtorek, 16 czerwca 2009, 11:10

AnsiString to klasa, a nie jakaś zmienna 8-bitowa! Typem 8-bitowym to może być typ char, ale nie klasa do przechowywania tekstu. A jeśli już mowa o unikodzie, to nikt nie powiedział, że jest to zawsze utf-16 (natywnie w windows). W protokole HTTP, jeśli chodzi o unikod, najczęściej (o ile nie jedynie) używane jest kodowanie utf-8, z racji oszczędności pamięci i zgodności z kodowaniem ASCII. AnsiString jest w stanie przechować unikod w tym kodowaniu, choć nie jest w stanie w pełni z nim współpracować - indeksowanie, obliczanie długości itd. Może pełnić rolę kontenera i nic więcej.


dobrze, dobrze, nic z tego nie wynika, problemu nie rozwiązałeś.

AnsiString rzeczywiście jest klasą, często po prostu o AnsiString i zmiennej typu String myślę tak samo.

Co do 8-bitów oto cytat z pliku pomocy do c++ builder 2007:


AnsiString ~2^31 characters 4 bytes to 2GB 8-bit (ANSI) characters, DBCS ANSI, MBCS ANSI, etc.




może przechowywać nawet zmienne 32-bitowe, ale nie jest w stanie przechować znaków Unicode. Jeżeli strona HTML zostanie zakodowana w Unicode, to będzie zawierać znaki unicode.

przykład: http://cyfbar.republika.pl/unicode.htm

niektóre strony swojego serwisu czasami kodowałem w unicode, dla wygody.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez Cyfrowy Baron » wtorek, 16 czerwca 2009, 11:12

W ostatniej aktualizacji podałem porady: Ściąganie plików z Internetu przez protokół HTTP (bez INDY), oraz: Wyświetlanie plików graficznych bezpośrednio z Internetu.
Co do drugiej z wyświetlaniem plików graficznych, to można po drobnej modyfikacji kodu wyświetlać dowolny plik o czym jest na końcu tej porady.

Tak więc korzystając z pierwszej porady ściągniesz na HDD dowolny plik z sieci, bez meczenia się z socketami czy też Indy.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez shycat » wtorek, 16 czerwca 2009, 11:29

Co do kodu strony -> tak jak pisalam, wczytywalam testowy kod strony wygenerowany w PHP

<?

for ($i=1; $i<=(100000); $i++)
{
echo"a";
}

?>

Co do laczenia... kod ktory podales niczego nie laczy... rownie dobrze mozna wczytac wynik do zmiennej... - oczywscie sprawdzilam to i bez zmian, czy do memo czy do zmiennej... na 100% pamietam, ze byla metoda jakiegos pobierania wyniku (przez Socket->ReceiveText(); ) gdzie pobieralo wieksze pliki... nie wiem czy to chodzilo o umieszczenie ReceiveText w petli... - pisalam juz o tym wyzej, czy cos zwiazane z bufforem...
Avatar użytkownika
shycat
Homos antropiczny
Homos antropiczny
 
Posty: 51
Dołączył(a): środa, 20 sierpnia 2008, 12:37
Lokalizacja: Śląsk
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: C++ Builder 2006, Delphi 7
Gadu Gadu: 26712716
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez Witold » wtorek, 16 czerwca 2009, 11:46

shycat napisał(a):Co do laczenia... kod ktory podales niczego nie laczy... rownie dobrze mozna wczytac wynik do zmiennej... - oczywscie sprawdzilam to i bez zmian, czy do memo czy do zmiennej..


Serio? Sprawdzałem, dla http://www.wp.pl, która przychodzi w kilku kawałkach (kilka razy wywoływana jest metoda ClientSocket1Read, zanim nazbiera się całość) , u Ciebie jest (tak jest na forum) AnsiString odp=Socket->ReceiveText(); to logiczne że zmienna odp zawierała by tylko ostatni fragment. Memo1->Lines->Add u mnie łączy te fragmenty, i mam całość strony. Podaj może jakiś sensowny kawałek kodu, skąd osoba która chce Ci pomóc ma wiedzieć jak to u Ciebie wygląda.
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez Cyfrowy Baron » wtorek, 16 czerwca 2009, 11:50

A czy próbowałaś skorzystać z porady: Ściąganie plików z Internetu przez protokół HTTP (bez INDY), to chyba najprostszy i najbardziej skuteczny sposób n a ściągnięcie dowolnego pliku z sieci.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez shycat » wtorek, 16 czerwca 2009, 12:08

to logiczne że zmienna odp zawierała by tylko ostatni fragment. Memo1->Lines->Add u mnie łączy te fragmenty, i mam całość strony. Podaj może jakiś sensowny kawałek kodu, skąd osoba która chce Ci pomóc ma wiedzieć jak to u Ciebie wygląda.


Problem w tym, ze u mnie jest pobierany pierwszy kawalek... nie ostatni... zeby uprzedzic ew. kolejne pytania i dziwne tezy - testowalam to rowniez na dlugim tekscie... zeby bez problemu dalo sie odroznic poczatek od konca - gdzie w samych literkach "a" moglby byc problem.

Cyfrowy Baronie, probowalam, dziala, ale ja musze uzyc socketu...
Avatar użytkownika
shycat
Homos antropiczny
Homos antropiczny
 
Posty: 51
Dołączył(a): środa, 20 sierpnia 2008, 12:37
Lokalizacja: Śląsk
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: C++ Builder 2006, Delphi 7
Gadu Gadu: 26712716
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez polymorphism » wtorek, 16 czerwca 2009, 12:15

dobrze, dobrze, nic z tego nie wynika, problemu nie rozwiązałeś.

Pisałem, że to jest wtrącone nawiasem. Miało wyprostować pewne nieścisłości, a nie rozwiązać problem.

może przechowywać nawet zmienne 32-bitowe, ale nie jest w stanie przechować znaków Unicode.

Nie zmienne 32-bitowe, tylko może (teoretycznie) pomieścić maksymalnie 2GB stringi (2^31 bajtów). Mylisz pojęcia...


Problem w tym, że ta strona nie jest poprawnie wyświetlana w przeglądarce (Firefox), a po zapisaniu na dysk nie widzę, żeby tam był jakiś unikod:
Kod: Zaznacz cały
<meta http-equiv="content-type" content="text/html; charset=iso-8859-2"> [...]

</head><body>˙ţ&lt;�h�t�m�l�&gt;�



[...]

Jak widać plik jest zapisany w kodowaniu iso-8859-2. Chodzi o coś takiego -> http://pl.wikipedia.org/wiki/Unicode. Zajrzyj do źródeł strony, zwróć uwagę na atrybut charset i na wszelkie znaki z ogonkami (np. w hex edytorze). Ba, spróbuj ją załadować do AnsiStringa!
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Socket, pobieranie zawartosci www

Nowy postprzez Witold » wtorek, 16 czerwca 2009, 15:04

shycat napisał(a):zeby uprzedzic ew. kolejne pytania i dziwne tezy


Dziwnie to Ty przedstawiłaś problem. Brak sensownego kodu aby go można było przetestować (to co ja napisałem do testów działa OK), brak adresu strony na której są problemy. Może problem sprawia kawałek kodu którego nie wkleiłaś, a zresztą …
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Aplikacje sieciowe

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 4 gości