Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   Crear componente de socket para cliente (https://www.clubdelphi.com/foros/showthread.php?t=61808)

Belaix 23-11-2008 00:43:38

Crear componente de socket para cliente
 
Hola

Quiero bajar un fichero de internet con mi aplicación desde consola en delphi

Estoy tratando de que funcione este procedimiento que he sacado de esta página:

(No se si es spam poner la dirección, por eso le pongo espacios ...)

http: // www . scalabium . com/faq/dct0116.htm

----------------------------------------------------
procedure DownloadFile(strHost, strRemoteFileName, strLocalFileName: string;
ClientSocket: TClientSocket);
var
intReturnCode: Integer;
s: string;
szBuffer: array[0..128] of Char;
FileOut: TFileStream;
begin
if
strRemoteFileName[1] <> '/' then
strRemoteFileName := '/' + strRemoteFileName;

FileOut := TFileStream.Create(strLocalFileName, fmCreate);
try
with
ClientSocket do
begin
Host := strHost;
ClientType := ctBlocking;
Port := 80;

try
Open;
{send query}
s := 'GET ' + strRemoteFileName + ' HTTP/1.0'#13#10 +
'Host: ' + strHost + #13#10#13#10;
intReturnCode := Socket.SendBuf(Pointer(s)^, Length(s));

if intReturnCode > 0 then
begin
{receive the answer}
{ iterate until no more data }
while (intReturnCode > 0) do
begin
{ clear buffer before each iteration }
FillChar(szBuffer, SizeOf(szBuffer), 0);

{ try to receive some data }
intReturnCode := Socket.ReceiveBuf(szBuffer, SizeOf(szBuffer));

{ if received a some data, then add this data to the result string }
if intReturnCode > 0 then
FileOut.Write(szBuffer, intReturnCode);
end
end
else
MessageDlg('No answer from server', mtError, [mbOk], 0);

Close;
except
MessageDlg('No connection', mtError, [mbOk], 0);
end;
end;
finally
FileOut.Free
end;
end;
To execute this procedure:
procedure TForm1.Button1Click(Sender: TObject);
begin
DownloadFile('URL Internet', '/forums.htm', 'd:\forums.htm', ClientSocket1);
end;
PS: the last parameter is ClientSocket component which you must drop on form from component pallete or create in run-time.
----------------------------------------------

No tengo ni puñetera idea de como puedo crear el clientsocket en tiempo real, teniendo en cuenta que mi aplicación es sobre consola.

Alguien podría darme un ejemplo? Llevo sólo 7 dias con delphi y ando mas perdido que un berebere en el polo norte.:rolleyes:

Belaix 23-11-2008 02:42:31

Bueno ... acabo de descubrir que poniendo esto :

ClientSocket1:=TClientSocket.create(ClientSocket1);

Se crea el el componente del socket.

Pero si pongo ...

Writeln ('HOLA');
ClientSocket1:=TClientSocket.create(ClientSocket1);

El programa me da un fallo de excepción de memoria ....

¿¿¿¿¿A que se debe esto?????

Belaix 23-11-2008 02:49:02

Joe ... llevo un buen rato con el tema ... no conseguía nada y por eso pregunté ... pero es hacer la pregunta en el foro y acabo de enterarme que si pongo:

ClientSocket1:=TClientSocket.create(nil);

Ya no falla el programa. No tengo ni idea que es eso de nil. Pero parece que funciona.

Ahora la pregunta es ...:

Me estoy bajando un archivo de un servidor en Internet con el programa de arriba, el cual me escupe un fichero con este contenido:

HTTP/1.1 505 HTTP Version Not Supported
Server: Apache-Coyote/1.1
Date: Sun, 23 Nov 2008 01:48:00 GMT
Connection: close


Estoy tratando de cambiar el comando get de la función ... y no tengo exito. Hay alguna forma de decirle el protocolo o la versión a utilizar como propiedad del socket?

cHackAll 23-11-2008 03:02:30

Aunque el problema parece estar claro;

Cita:

Empezado por Belaix (Mensaje 327469)
s := 'GET ' + strRemoteFileName + ' HTTP/1.0'...

Cita:

Empezado por Belaix (Mensaje 327474)
...HTTP/1.1 505 HTTP Version Not Supported...


Te aconsejo considerar usar métodos existentes y probados en el foro, para ello busca la palabra "InternetReadFile".

PD; Usa las etiquetas [delphi] código [/delph¡]

Suerte

Belaix 23-11-2008 04:27:25

Ya probé cambiar el http por 1.1 entre otras 50.000 pruebas ... y sigue diciendo lo mismo.

Sólo lo dice en el servidor donde quiero bajar el archivo, en cualquier otro funciona perfectamente.

El problema supongo que debe ser que la URL tiene un interrogante estilo:

/indice.to?nombre HTTP/1.0

si me descargo 'indice.to' solamente, lo hace perfectamente. He probado de sustituir el ? por %3F ... y tampoco ...

Ya no se que hacer :(

Sobre la alternativa de ... InternetReadFiles ...

http://www.cryer.co.uk/brian/delphi/..._file_http.htm (esta página me ayudó ...)

Desgraciadamente no me vale (esa fue mi segunda opción), porque es lenta en ejecución. Necesito que baje este archivo 20 veces por segundo ... y con esta opción deja mi ordenador K.O.

Actualmente mi programa, descarga el archivo mediante la aplicación wget.exe que sirve para eso ... desde msdos, y le llamo mediante winexec. Y después otra vez tengo que abrir el archivo descargado para trabajar con el. Como ves ... no es muy práctico. Pero es algo más rápido que la opción de InternetReadFiles, sorprendentemente ....

Jugar con los sockets, debería ser de las 3 opciones que tengo la más rápida con diferencia no?. Pero no lo consigo :(

¿Alguna sugerencia?

seoane 23-11-2008 15:20:01

:confused: Solo por curiosidad ¿por que bajas ese archivo 20 veces por segundo?

No se que tipo de proyectos estas llevando a cabo pero me parece que el protocolo http no es el mas adecuado para esto. De todas formas usando wininet no debería se tan lento, prueba a mantener la conexión activa y no cerrarla y abrirla cada que que hagas una petición al servidor, esto reducirá bastante el tiempo.

Por cierto, dices que esta url te falla:
Código Delphi [-]
/indice.to?nombre HTTP/1.0

Esa es la que te falla o es una parecida :confused:


La franja horaria es GMT +2. Ahora son las 11:29:40.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi