CurlPas + Wysylanie kilku plikow

0

Witam, pisze sobie program do wysylania pliczkow na serwer w oparciu o CurlPas.
No i mam problem :/ Mianowicie po uruchomieniu programu plik jest przesylany - JEDEN PLIK.
Dzieje się to w wątku. Wątek się kończy i zwracany jest link do pliku. Wszystko fajnie, itd. ALE gdy klikne ponownie button uruchamiający wątek, to program wykrzacza się dająć mi error "Accesc Violation ...adres... " in "msvcrt.dll" :/

Nie wiem jak zobie z tym poradzić :/

Oto kawałek kodu odpowiedzialny za innicjalizacji Curl'a oraz wysylania pliku

type upShareBase = class(TThread)
 private
  obCurl : TCurl;
  kodHTML : string;
  procedure OnRecive(Sender:tObject; data:pChar; len:LongWord; var bContinue:Boolean);
procedure Progress(Sender: TObject; BytesTotal, BytesNow:longint; var bContinue:Boolean);
  function getNumerSerwera : string;
 protected
 procedure execute; override;
 end;
procedure upShareBase.OnRecive(Sender: tObject; data: pChar; len: LongWord;
  var bContinue: Boolean);
begin
 kodHTML := kodHTML + data;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
 up := upShareBase.Create(false);
end;
procedure upShareBase.Execute 
 var NumerSerwera : string;
     anLink : TMatch;
     i : integer;
begin
 inherited;
   sleep(100);

 obCurl := TCurl.Create(nil);
 obCurl.URL := 'http://sharebase.to';
 obCurl.OnReceive := OnRecive;

 obCurl.Perform;
 obCurl.Clear;
 sleep(1000);
 obcurl.Timeout := 40000;

 obCurl.FreshConnect := False;
  NumerSerwera := getNumerSerwera;
 kodHTML := '';
  //  form1.Memo1.Lines.Add(numerserwera);


  obCurl.URL := 'http://sr'+NumerSerwera+'.sharebase.to/upload/';
  obCurl.Referer := 'http://sharebase.to';

  obCurl.FormData.Add('usrv','sr'+NumerSerwera,'',POST_TYPE_PLAIN);
 obCurl.FormData.Add('umid','','',POST_TYPE_PLAIN);
 obCurl.FormData.Add('ufile','c:\ttt2.rar','multipart/form-data',POST_TYPE_ATTACHMENT); // tutaj plik
 obCurl.FormData.Add('101','Upload Now !','',POST_TYPE_PLAIN);
 obCurl.FormData.Add('ulaid','','',POST_TYPE_PLAIN);
 obCurl.OnProgress := Progress;
 obCurl.OnReceive := onRecive;

 obcurl.Verbose := true;
    if not obcurl.Perform then form1.Memo1.Lines.Add(obcurl.ErrorString);


 obCurl.Destroy;



   anLink := nil;
  anLink := Form1.Ereg(kodHTML,'http://sharebase.to/files/|">');
  for i := 0 to high(anlink) do
   begin
    if (anlink[i] <> '') and not (Pos('/',anlink[i])>0) then
 form1.Memo1.Lines.Add('http://sharebase.to/files/'+anlink[i])       // zwraca kawalek linku
   end;

I tak jak pisalem, po uruchomieniu programu, i kliknieciu na Button, plik zostaje wyslany - a link do niego zostaje zwrocony w TMemo.

Jednak gdy drugi raz klikne na button, to plik pobierze jedynie kod html strony, ale plik nie zostanie już wysłany bo program wykrzaczy się errorem z udziałem msvcrt.dll :/

Program docelowo ma obslugiwac mój serwer - jednak na razie jeszcze go nie kupiłem dlatego też testuję wysyłanie na Sharebase.to z racji łatwości obłsugi (brak captcha itd.)

// Ewentualnie poszukuje jakiegoś komponentu w stylu Curl -> odpada użyci WinInet (np. ten sposob z 4p).

0
mr.hex napisał(a)
procedure TForm1.Button2Click(Sender: TObject);
begin
 up := upShareBase.Create(false);
end;

Tworzysz obiekt za pierwszym razem, który po zakończeniu nie jest zwalniany, dlatego przy kolejnym kliknięciu na button otrzymujesz błąd "Access violation..."

0

Nawet jak dodam do wątku FreeOnTerminate, albo dokleje pod koniec wątku coś w stylu

if Assigned(up) then
up.FreeOnTerminate := TRUE;

itd. to nic nie daje :/ Nadal ten sam error.

0

Ustaw FreeOnTerminate := True, bezpośrednio w procedurze Execute wątku lub zwolnij go ręcznie sam, bo jego zakończeniu.
Możliwe jeszcze, że problem jest z dostępem do komponentów widocznych na formie (jak TMemo), komunikat powinien być inny, jedna również możesz spróbować użyć metody Synchronize().

0

@mordek - to na pewno nie ma nic wspólnego ze zwalnianiem pamięci czy dostępem do wizualnych komponentów.

@mr.hex - wykonaj drugi wątek linijka po linijce i zobacz, w którym miejscu się wykrzacza.
getNumerSerwera() - czy jest thread-safe?
a może sharebase nie pozwala na równoległe uploady?
albo jakimś cudem plik, z którego curl usiłuje czytać jest blokowany przez pierwszy wysyłający wątek?

0

Eh.. getNumerSerwera - funkcja pobiera przez TidHTTP.GET kod strony i wyłuskuje z kodu numer serwera na jaki ma zostać wysłany plik.

Ustawilem w Execute wątku FreeonTerminate na true - nadal to samo.

Plik z pewnoscia nie jest blokowany :/ Nie staram sie tez uploadować X plików na raz, tylko po kolei, robiłem nawet odstepy po 1min - nadal to samo :/

Nie wiem, moze to błąd komponentu ?
Zaznacz mi linijke : Result:=curl_easy_perform(aCurl); w ocurltthd.inc

Dokładna treść błędu:

Project sharebase.exe raised exception class EAccesViolation with message 'Acces violation at address 77C378AC in module 'msvcrt.dl'. Read of addres 706D6126'. Process stopped. User Step or Run to continue.

Gdy puscze sam wątek wysyłania pliku, to plik jest wysyłany. Jeżeli natomiast chce przed tym pobrać kod strony, czy to używając CurlPas czy też TidHTTP to zawsze wyskakuje ten error :/ Totalnie już nie wiem o co chodzi ;/

Aha, probowalem z użyciem Synchronize przy wpisywaniu danych do TMemo - to samo. Nawet <ort>usunolem </ort>wpisywanie danych do TMemo, a wyniki obserwowalem na snifferze - nadal ten cholerny error ;/

Może znacie panowie jakiś komponent w działaniu podobny do CurPas (bindy pod Curl) ? Myslalem nad wget, co prawda nie komponent, ale niestety nie jest on w stanie dać mi tego czego potrzebuje. Jest do dyspozycji łącze 100MB - a wget uploaduje/ściaga z predkoscią ok 2-3MB. A w przeglądarce idzie po min.5-6MB.

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