PDA

Ver la Versión Completa : Me da error al quitar el componente ClientSocket1


Antuan
11-09-2005, 10:18:19
Bueno como no dejo de ser novato pues tengo un problema que no veo como arreglarlo y a lo mejor me he opcecado y no lo veo.
Es un form que lo estoy mirando por programacion y en concreto con un componente no visual el TClientSocket.
Me da error al compilar
Si inclullo el componente visualmente en el form y no defino la variable en la seccion private, entonces me funciona bien.
Pero si quito el componente ClientSocket de form1 y lo defino en la seccion private ClientSocket1: TClientSocket; entonces me da un error al compilar.
seguro que hago algo mal.
Me podeis decir que es.
Muchas gracias.
Este es el form1

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Sockets, ScktComp;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
ClientSocket1: TClientSocket;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
ClientSocket1.ClientType := ctNonBlocking;
ClientSocket1.Name:= 'ClientSocket1';
ClientSocket1.Host := 'www.villademostoles.da.ru';
ClientSocket1.Port := 80;
ClientSocket1.OnRead:= ClientSocket1Read;
ClientSocket1.Active := True;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with ClientSocket1.Socket do begin
SendText('GET http://www.villademostoles.da.ru HTTP/1.1'+#13#10);
SendText('Accept-Language: es'+#13#10);
SendText('Accept-Encoding: gzip, deflate'+#13#10);
SendText('User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'+#13#10);
SendText('Host:www.villademostoles.da.ru'+#13#10);
SendText(''+#13#10);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Close;
end;
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
begin
memo1.Lines.Add(ClientSocket1.Socket.ReceiveText);
end;
end.

Sirkius
11-09-2005, 10:50:16
Si no lo pones como componente, que se crea automaticamente al crear el form, deberás crearlo antes de nada.

En el FormCreate antes de nada:

ClientSocket1 := TClientSocket.Create(Self);

Y para mayor seguridad en el FormClose:

ClientSocket1.Free;

Antuan
11-09-2005, 12:05:31
Perfecto me funciona bien.
Muchas gracias
Como estoy aprendiendo y buscando cosas, y experimentando.
¿Se podria pasar el codigo del boton a una funcion?


procedure TForm1.Button1Click(Sender: TObject);
begin
with ClientSocket1.Socket do begin
SendText('GET http://www.villademostoles.da.ru/index.html HTTP/1.1'+#13#10);
SendText('Accept-Language: es'+#13#10);
SendText('Accept-Encoding: gzip, deflate'+#13#10);
SendText('User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'+#13#10);
SendText('Host:www.villademostoles.da.ru'+#13#10);
SendText(''+#13#10);
end;
end;

dec
11-09-2005, 15:19:57
Hola,


¿Se podria pasar el codigo del boton a una funcion?

Una función tiene que devolver algún resultado... ¿Qué resultado tendría que devolver el código anterior? ;) Si fuera el "ReceiveText" del "Socket" podrías probar a crear el mismo dentro del cuerpo de una función, inicializarlo y luego que la función devolviera una cadena de caracteres ("string") con el "ReceiveText", propiamente. Tal vez la función podría contar con un parámetro, también de tipo "string", en el que pudiera enviarse la dirección URL que parece ser necesaria y de la que se quiere obtener el "ReceiveText".

Antuan
11-09-2005, 16:22:14
Como ves he caido de nuevo en delphi.
El el primer hilo tengo lo que devuelve
que es esto

memo1.Lines.Add(ClientSocket1.Socket.ReceiveText);

Pero lo logico es que lo devuelva como dices en el ReciveText en un EditText.
Intentare lo que dices pero al hacer la funcion me dice que el componente ClientSocket1 no esta definido y sin embargo en el apartado private lo tengo definido.
Volvere a dejarlo de nuevo y seguir con lo que estaba haciendo hasta que coja nivel.

Sotrono
11-09-2005, 16:31:41
Lo mas apropiado para eso es utilizar un procedimiento en vez de una funcion.
Lo declaras en la seccion private

procedure PeticionWeb;

y en implementation


procedure TForm1.PeticionWeb;
begin
with ClientSocket1.Socket do begin
SendText('GET http://www.villademostoles.da.ru/index.html HTTP/1.1'+#13#10);
SendText('Accept-Language: es'+#13#10);
SendText('Accept-Encoding: gzip, deflate'+#13#10);
SendText('User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'+#13#10);
SendText('Host:www.villademostoles.da.ru'+#13#10);
SendText(''+#13#10);
end;

end;

Lo podes mejorar para que en vez de que siempre realice la peticion de la misma pagina, que se le pasen los parametros de la web que se quiere llamar.
Espero que te haya servido...

Edicion: Declara la funcion de la misma forma que declaro este procedimiento y te va a reconocer el ClientSocket1.

Antuan
11-09-2005, 18:04:05
Bien pues eso, que con el procedure he resuelto el problema y he modificado el codigo para ver varias web con un edit1.text
Pero tengo que pulsar dos veces con el raton el en boton
La primera no aparece nada y la segunda vez si
Lo he intentado haciendo una funcion y no reconoces el ClientSocket1
Bueno muchas gracias y poco a poco creo que lo ire sacando. Supongo.
Aunque con vuestra ayuda tambien voy aprendiendo y bastante.
La siguiente fase sera evitar tener que pulsar 2 veces el raton y si lo consigo intentare que el resultado en vez de darlo en un memo me lo de en un EditText.

dec
11-09-2005, 18:25:09
Hola,

Antuan, echando un vistazo a la ayuda de "TClientSocket" y temas relacionados me doy cuenta de lo poco que sé de ellos. Quiero decir que hacer la función, como dije arriba, no se ve tan sencillo como acaso di a entender. Se me ocurre una forma de rectificar, y es, ¿qué quieres conseguir exactamente? ¿qué información tratas de lograr? ¿Qué se supone que ha de haber en la propiedad "ReceiveText"? Lo digo por ver si podría lograrse de algún otro modo echarte una mano.

Antuan
11-09-2005, 19:08:40
Ya lo he conseguido y pongo el codigo a disposicion del que lo necesite pero dejo que alguien me ayude como siempre para no tener que pulsar el boton 2 veces.
Se trata de sacar todo el codigo de una url incluso las cabeceras.
Yo como soy un novato aun no esta del todo depurada pero funciona.
es un formulario con dos botones, una labe,l un EditText y um MemoEdit.
Este es el codigo

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Sockets, ScktComp;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Edit1: TEdit;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
ClientSocket1: TClientSocket;
function PeticionWeb(var url: string):string;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
ClientSocket1 := TClientSocket.Create(Self);
ClientSocket1.ClientType := ctNonBlocking;
ClientSocket1.Name:= 'ClientSocket1';
ClientSocket1.Host := 'www.auna.com';
ClientSocket1.Port := 80;
ClientSocket1.OnRead:= ClientSocket1Read;
ClientSocket1.Active := False;
end;
function TForm1.PeticionWeb(var url: string):string;
begin
result:= ' ';
with ClientSocket1.Socket do begin
Memo1.Clear;
ClientSocket1.Host := url;
ClientSocket1.Active := True;
SendText('GET / HTTP/1.0'+#13#10);
SendText(''+#13#10);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var url: string;
begin
url:= Edit1.Text;
PeticionWeb(url);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Close;
end;
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
begin
memo1.Lines.Add(ClientSocket1.Socket.ReceiveText);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ClientSocket1.Free;
end;
end.

Sotrono
11-09-2005, 20:01:53
Hey, muchas gracias, justo estaba buscando como manejar los eventos de los objetos creados en tiempo de ejecucion

ClientSocket1.OnRead:= ClientSocket1Read;

Con esta linea aprendi.

Una cosa, si la funcion PeticionWeb no va a devolver ningun resultado te conviene utilizar un procedimiento.

Antuan
11-09-2005, 20:12:40
Me interesa la funcion pero lo que no se hacer es como devolver el resultado del ClientSocket1.Socket.ReceiveText en un string en vez de en un MemoEdit.
Yo solo necesito las cabeceras y el codigo que he puesto da las cabeceras y la pagina completa.

Crandel
12-09-2005, 07:02:03
Antuan, ahora que ya casi tienes el código, te recomiendo que avances al paso siguiente y crees una clase a que resuelva tu problema.

Aca te dejo algunas correcciones a tu código (los comentarios son todos códigos que no deben ir):

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Sockets, ScktComp;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Edit1: TEdit;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
ClientSocket1: TClientSocket;
// lo cambie
procedure PeticionWeb(url: string);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
ClientSocket1 := TClientSocket.Create(Self);
ClientSocket1.ClientType := ctNonBlocking;
// ClientSocket1.Name:= 'ClientSocket1'; no modificar el name
// ClientSocket1.Host := 'www.auna.com'; para que asignarle una propiedad que vas a modificar despues
ClientSocket1.Port := 80;
ClientSocket1.OnRead:= ClientSocket1Read;
ClientSocket1.Active := False;
end;
// esta función siempre devuelve una cadena vacia
// tampoco va el var
//function TForm1.PeticionWeb(var url: string):string;
procedure TForm1.PeticionWeb(url: string);
begin
result:= ' ';
with ClientSocket1.Socket do
begin
Memo1.Clear;
ClientSocket1.Host := url;
ClientSocket1.Active := True;
// muy posiblemente este código no deba estar aca
// sino en el evento onConnect para que te responda con un solo click
SendText('GET / HTTP/1.0'+#13#10);
SendText(''+#13#10);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
//var url: string;
begin
// url:= Edit1.Text;
//PeticionWeb(url);
// reemplazamos todo por:
PeticionWeb(Edit1.Text);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Close;
end;
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
begin
memo1.Lines.Add(ClientSocket1.Socket.ReceiveText);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ClientSocket1.Free;
end;
end.

Antuan
12-09-2005, 09:55:32
Hola Angel muchas gracias por las correciones, de esta manera es como se aprende.
Se me olvido comentar un pequeño fallo y es que mientras que este activo el ClientSocket1 mo me deja hacer una nueva peticion asi que me tendre que comer los puños como aqui se dice y seguir investigando.
Sobre la funcion que me devuelva la respuesta en un memo en vez que lo haga en un string. Me comentas que tengo que crear una nueva clase.
Llevo muy poco tiempo con Delphi pracicamente nada. Le estoy entrando al Pascal y atraves de esto voy cogiendo poco a poco a Delphi.
Asi que no seas malo y dame una idea de como hacerlo.
A ver si al final dejo una funcion en condiciones para que los amigos como yo que sabemos muy poco.
Muchisimas gracias por vuestra ayuda.

Crandel
12-09-2005, 20:32:59
Se me olvido comentar un pequeño fallo y es que mientras que este activo el ClientSocket1 mo me deja hacer una nueva peticion asi que me tendre que comer los puños como aqui se dice y seguir investigando.
Creo que deberias hacer es cerrar la conexión antes de abrir otra. Al hacer peticiones a las paginas web, la conexion se cierrar automaticamente cuando finaliza la transferencia, de otra forma tenes que cerrarla vos.

Sobre la funcion que me devuelva la respuesta en un memo en vez que lo haga en un string. Me comentas que tengo que crear una nueva clase.
Son dos cosas diferentes, una cosa es crear una clase y otra es que la función te devuelva el string.
Lo que pasa que quien captura la respuesta de la pagina web es el evento OnRead y no tu procedimiento PeticionWeb.

Llevo muy poco tiempo con Delphi pracicamente nada. Le estoy entrando al Pascal y atraves de esto voy cogiendo poco a poco a Delphi.
Asi que no seas malo y dame una idea de como hacerlo.
Lo de la clase lo vemos cuando termines tu aplicación web, porque aprender a crear clases es todo un tema y mejor lo manejamos por separado, una vez que lo tengas terminado.

A ver si al final dejo una funcion en condiciones para que los amigos como yo que sabemos muy poco.
Muchisimas gracias por vuestra ayuda.
Me parece muy bien, y de nada.

Antuan
14-09-2005, 14:53:14
Como se escribe la etiqueta citar? No lo he visto en las etiquetas de VB
Tambien aprovecho y como se trata del mismo tema.
Como declaro el componente ClientSocket en una aplicacion DLL sin form para que se le puedan asignar las propiedades y los eventos.
Muchas gracias de nuevo.