21. april 2009 - 15:12Der er
15 kommentarer og 1 løsning
Kopier fil over tcp forbindelse
Som et lille hjørne af et større projekt har jeg brug for at kopiere en fil fra en server til en klient.
Serverprogrammet skal af specielle årsager programmeres i D2007
Klientprogrammet sender en streng til serverprogrammet som udfører nogle ting på serveren, genererer en temporær fil, som klienten så modtager og gemmer lokalt.
Det lyder og burde være meget simpelt, men kan ikke få det til at virke. Bruger Indy 10 komponenter. Det er kun selve kopierings-delen jeg er i tvivl om. Jeg har prøvet med både de alm. tcpserver- og tcpclient-komponenterne og også indys FTP komponenter. Alle eksempler man kan finde på nettet er lavet vha Indy 9 og virker ikke med Indy 10.
Burde som sagt være simpelt. Noget i stil med at serversiden tager en fil og streamer den over til klienten via tcp-forbindelsen. Klienten samler streamen igen og gemmer den til en fil.
Synes efterhånden jeg har prøvet alt - uden held..
Således sender jeg en fil fra min server til en klient, bruger Indy 10, jeg har fjernet en del kode for at gører det mere overskueligt, jeg håber ikke jeg har fjernet for meget
Server:
I IdTCPServerExecute:
procedure SendOpdatering; var Stream : TFileStream; begin try Stream:=TFileStream.Create(MinFil,fmOpenRead); try AContext.Connection.IOHandler.Write(Stream,0,true); finally Stream.Free; end; end; except on E: Exception do begin SkrivLog('Fejl i SendOpdatering: '+E.Message,true); end; end; end;
Glemte at nævne at i noget af den kode jeg har klippet der sender klienten først en lille streng til serveren med besked om at der skal sendes en fil hvorefter serveren sender en lille streng retur med filnavnet og derefter kommer så selve filen.
Jeg bruger Indy 10.2.3 og som nævnt virker ovenstående kode uden problemer. Hvis du ikke kan få det til at virker kan det måske være fordi du benytter en ældre Indy version som havde en hel del fejl.
Har forsøgt at gøre det så simpelt som muligt ved at lave en serverapp kun med en tcpserver-komponent, hardcode host/port osv, og det samme med klienten, men noget går galt undervejs.
Klienten kommer med en 10022 - invalid arguments, når man siger connect.
Her er hvad jeg har:
Server: -------------
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext); var Stream : TFileStream; begin try Stream:=TFileStream.Create('c:\test.pdf',fmOpenRead); try AContext.Connection.IOHandler.Write(Stream,0,true); finally Stream.Free; end; except on E: Exception do begin ShowMessage('Fejl: '+E.Message); end; end; end;
procedure TOpdateringThread.Execute; var Stream : TFileStream; begin try IdTCPClient.Connect; Stream:=TFileStream.Create('c:\temp\bummelum.pdf',fmCreate); IdTCPClient.IOHandler.ReadStream(Stream,-1,false); Stream.Free; except on E: Exception do ShowMessage('Fejl: '+E.Message); end;
IdTCPClient.Free; end;
-----------
og så en knap på klienten som kreerer en tråd og kalder trådens execute procedure:
procedure TForm1.Button1Click(Sender: TObject); var Thread: TOpdateringThread; begin Thread := TOpdateringThread.Create('localhost'); Thread.Execute; end;
-----
har prøvet at køre både server og klient på localhost, men har også forsøgt at smide server app'en på en anden maskine - samme fejl..
Denne linie i trådens create: inherited Create(False); //constructor Create(CreateSuspended: Boolean);
angiver med false at tråden _ikke_ skal creates Suspended, dvs. at Execute kaldes automatisk straks efter at tråden er oprettet.
Så det også står i hjælpen: Call Create to create a thread in an application. If CreateSuspended is False, Execute is called immediately. If CreateSuspended is True, Execute won't be called until after Resume is called.
Nu er det selfølgelig ikke et krav at du henter filen i en tråd men det giver jo den fordel at dit program ikke "hænger" mens filen hentes. Du kan jo så benytte OnTerminate til at få at vide når filen er hentet.
Kan det være en fordel at skrive serverens onexecute ved hjælp af threads også, så den kan sende filer til flere klienter samtidigt, eller ligger det i serverkomponentens natur at den kan det?
Det styrer server komponenten automatisk, som du har lavet det nu kan serveren sende til mange på samme tid uden problemer.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.