Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido) TClientSocket no Delphi 7


Guest Thieres Tembra

Pergunta

Guest Thieres Tembra

Olá amigos, estou com um grande problema que não consigo resolver.

Eu tenho um Memo onde cada linha contém um site.

Eu preciso percorrer linha por linha deste Memo abrindo uma conexão por socket com cada um.

Sendo que um de cada vez, ou seja, abro o socket para o primeiro, envio o GET da página, aguardo a resposta, finalizo o socket, modifico o HOST, abro o socket para o segundo e assim sucessivamente.

O meu código é o seguinte:

procedure TForm1.VERIFICARClick(Sender: TObject);
var
  I,QTD,POS : integer;
  URL,SOCKTXT : string;
begin
QTD := LISTA.Lines.Count;
I := 0;
while I <= QTD-1 do
begin
  URL := LISTA.Lines.Strings[I];
  if RightStr(URL, 1) <> '=' then
  begin
    //nada
  end
  else
  begin
    if (LeftStr(URL, 7) <> 'http://') then
      URL := 'http://'+URL;
    VERIFY.Close;
    VERIFY.Host := URL;
    VERIFY.Port := 80;
    VERIFY.Active := True;
    SOCKTXT := 'GET '+URL+' HTTP/1.0';
    VERIFY.Socket.SendText(SOCKTXT);
  end;
  Inc(I);
end;
end;

Porém ele dá Socket Error 10049.

Eu não implementei as funções OnRead, OnConnect e OnWrite do TClientSocket (VERIFY) por não saber o que botar.

Já pensei em criar um timer e de 5 em 5 seg ele visita o site, mas isso não é o correto, afinal de contas ele só pode visitar o próximo assim q concluir o primeiro, o que pode levar menos ou mais do que 5 seg.

Por favor me ajudem =]

Link para o comentário
Compartilhar em outros sites

6 respostass a esta questão

Posts Recomendados

  • 0

Socket Error 10049. Não é possível atribuir endereço solicitado.

O endereço pedido não é válido em seu contexto. Normalmente é o resultado de uma tentativa para ligar a um endereço

que não é válido para a máquina local, ou connect/send para um endereço ou porta que não são válido para uma

máquina remota (por exemplo porta 0).

Socket Error 10049. Não é possível atribuir endereço solicitado.

Resposta / Solução: Normalmente os resultados de uma tentativa de criar um socket com um endereço não nesta máquina.

WinSock descrição: O "endereço", remete para o soquete nome remoto (protocolo, porta e endereço).

Esse erro ocorre quando o sin_port valor for igual a zero em uma estrutura sockaddr_in para ligar ou sendto.

Este erro também ocorre quando você está tentando nome do soquete locais (ceder locais endereço e número da porta), com vínculo, mas Windows Sockets não atribuem esse erro de vincular por alguma razão desconhecida.

Com relação ao erro 10049...tambem ocorre quando você tenta atribuir um IP local arbitrário para os componentes TIdPOP3 e/ou TIdSMTP através da propriedade BoundIP? Se for o caso, deixe essa propriedade em branco ou atribua um IP que corresponda à máquina onde você está executando o programa.

OBS: rodei o seu codigo usando apenas um endereço e a resposta foi :

Windows socket error: O nome solicitado é válido e foi econtrado no banco de dados, mas os dados corretos associados não estão resolvidos (11004), on API ASync Lokup. Process stopped

veja o que acontece quando voce usa apenas um endereço.

Link para o comentário
Compartilhar em outros sites

  • 0

Thieres Tembra, observe os comentários do colega Jhonas e, de minha parte, deixo algumas sugestões que eventualmente podem ajudar a sanar algum problema.

- Evite a possibilidade de haver qualquer caracter inesperado, como espaço no início e fim da linha sendo processada já que você testa especificamente sequencias nestes extremos; (pode influenciar em um endereçamento incorreto)

- Enxugue seu código utilizando um for..to..do no lugar de um while..do;

- Ajuste a lógica de modo a utilizar if's úteis. Contornando o teste, você pode evitar aquele if onde você faz nada;

Eu não implementei as funções OnRead, OnConnect e OnWrite do TClientSocket (VERIFY) por não saber o que botar.
Segue uma sugestão. Acho que pode funcionar:

type
  TForm1 = class(TForm)
    ...
  private
    { Private declarations }
    ReceivedAnswer :Boolean;
  end;
...
procedure TForm1.VERIFICARClick(Sender: TObject);
var
  I : integer;
  URL, SOCKTXT : string;
begin
  for I := 0 to LISTA.Lines.Count -1 do
  begin
    URL := Trim(LISTA.Lines.Strings[I]);  // ** retire qualquer caracter espaço no início ou fim
    if RightStr(URL, 1) = '=' then
    begin
      if (LeftStr(URL, 7) <> 'http://') then
        URL := 'http://'+URL;
      VERIFY.Close;
      VERIFY.Host := URL;
      VERIFY.Port := 80;
      VERIFY.Active := True;
      SOCKTXT := 'GET '+URL+' HTTP/1.0';

     // inicializamos variável para controle
      ReceivedAnswer := False;
      VERIFY.Socket.SendText(SOCKTXT);
    // após enviado o comando, aguardamos pela resposta ou desconexão do socket
      while VERIFY.Active and
            not ReceivedAnswer do
        Application.ProcessMessages;  // evita que sua aplicação congele
    end;
  end;
end;

procedure TForm1.VERIFYRead(Sender: TObject; Socket: TCustomWinSocket);
var
  ReceivedCmd :String;
begin
 // armazena na variável o texto recebido e faz algo com ele...
  ReceivedCmd := Socket.ReceiveText;
 // Seta variável indicando que a resposta foi recebida
  ReceivedAnswer := True;
end;

Porém ele dá Socket Error 10049.

OBS: rodei o seu codigo usando apenas um endereço e a resposta foi :

Windows socket error: O nome solicitado é válido e foi econtrado no banco de dados, mas os dados corretos associados não estão resolvidos (11004), on API ASync Lokup. Process stopped

Jhonas, eu já observei em outra oportunidade que o erro citado pelo colega não necessariamente ocorre de primeira. Neste seu exemplo, após ocorrido este erro que você citou, se você tentar uma conexão seguida, o tal erro deverá ser retornado (pelo menos, isto ocorreu comigo).

Assim, parece que nosso colega pode estar recebendo um outro erro antes deste e não mencionou.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Obrigado pelas dicas Micheus e Jhonas.

Eu ajeitei meu código, mas ainda assim não funciona.

Ficou deste jeito

procedure TForm1.VERIFICARClick(Sender: TObject);
var
  I,POS : integer;
  URL,GETVAR,SOCKTXT,CMD : string;
begin
CMD := LINK.Text;
if (RightStr(CMD, 1) <> '?') then
  CMD := CMD+'?';
for I := 1 to LISTA.Lines.Count -1 do
begin
  URL := Trim(LISTA.Lines.Strings[I]);
  if RightStr(URL, 1) = '=' then
  begin
    if (LeftStr(URL, 7) = 'http://') then
      URL := MidStr(URL, 8, length(URL)-7); //retira http:// da frente
    POS := PosEx('/', URL, 1);
    GETVAR := MidStr(URL, POS, length(URL)-POS+1)+HTMLEncode(CMD); //pega somente o arquivo desejado, exemplo: /index.php?page=inicio
    URL := MidStr(URL, 1, POS-1); //pega somente o host, exemplo: www.meusite.com

    SVERIFY.Active := False;
    SVERIFY.Close;
    SVERIFY.Host := URL;
    SVERIFY.Open;
    SVERIFY.Active := True;
    SOCKTXT := 'GET '+GETVAR+' HTTP/1.0'+chr(13)+chr(10)+chr(13)+chr(10);

    //inicilizando variável para controle
    RECEIVEDANSWER := False;
    SVERIFY.Socket.SendText(SOCKTXT);

    //aguardando pela resposta ou desconexão do socket
    while SVERIFY.Active and
          not RECEIVEDANSWER do
      Application.ProcessMessages;  // evita que a aplicação congele
  end;
end;
end;
Ele continua dando o mesmo erro, mas eu mudei a sequencia dos sites na LISTA, e ele deu um outro erro. Então eu creio que isso seja um erro quando ele não consegue se conectar ao site, porém em vez de prossegur e ir para o próximo site ele finaliza o programa. Não sei o que está acontecendo ainda. Também estava tentando por outro método, utilizando o IdHTTP.Get segue o código
procedure TForm1.VERIFICARClick(Sender: TObject);
var
  I : integer;
  URL,CMD : string;
  RESPOSTA: TStringStream;
begin
CMD := LINK.Text;
if (RightStr(CMD, 1) <> '?') then
  CMD := CMD+'?';
for I := 0 to LISTA.Lines.Count -1 do
begin
  URL := Trim(LISTA.Lines.Strings[I]);
  if RightStr(URL, 1) = '=' then
  begin
    if (LeftStr(URL, 7) <> 'http://') then
      URL := 'http://'+URL;
    RESPOSTA := TStringStream.Create('');
    try
      VERIFY.Host := URL;
      VERIFY.Get(URL+HTMLEncode(CMD), RESPOSTA);
    finally
      RESPOSTA.Free;
    end;
  end;
end;
end;

Mas também apresenta erros de Acess Violation.

Ta complicado.

=/

Link para o comentário
Compartilhar em outros sites

  • 0
Ele continua dando o mesmo erro, mas eu mudei a sequencia dos sites na LISTA, e ele deu um outro erro.

Então eu creio que isso seja um erro quando ele não consegue se conectar ao site, porém em vez de prossegur e ir para o próximo site ele finaliza o programa.

Quanto a esta questão, pode ser resolvida tratando a exceção. Modifique esta parte do código:

...
    URL := MidStr(URL, 1, POS-1); //pega somente o host, exemplo: www.meusite.com

        SVERIFY.Close;
        SVERIFY.Host := URL;
    try
          SVERIFY.Open;
          SOCKTXT := 'GET '+GETVAR+' HTTP/1.0'+chr(13)+chr(10)+chr(13)+chr(10);

         //inicilizando variável para 
          RECEIVEDANSWER := False;
          SVERIFY.Socket.SendText(SOCKTXT);

         //aguardando pela resposta ou desconexão do socket
          while SVERIFY.Active and
                 not RECEIVEDANSWER do
            Application.ProcessMessages;  // evita que a aplicação congele
        except
          // se precisar por alguma mensagem sobre o erro na conexão
          // é aqui que você a coloca, do contrário, basta colocar nada
        end;
  end;
end;
end;
Sobre estas linhas:
SVERIFY.Active := False;
SVERIFY.Close;

Estas operações fazem a mesma coisa, apenas que uma você atua sobre a propriedade (Active) e outra você usa um método (Open). Então você precisa apenas utilizar uma delas.

Talvez, fosse conveniente que você colocasse as strings que você está processando (o conteúdo de seu memo) para que alguém possa testar com mais "realismo" a sua situação.

Bom, de minha parte é só. Espero que o colega Jhonas possa continuar lhe auxiliando. (retorno apenas 17/12/07)

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

colega, dei uma modificada no seu codigo e testei no delphi 5... aparentemente não deu mais erro

procedure TForm1.Button1Click(Sender: TObject);
var
  I,tag : integer;
  URL,GETVAR,SOCKTXT,CMD,S : string;
begin

for I := 0 to LISTA.Lines.Count do
begin
  showmessage(inttostr(i));
  URL := Trim(LISTA.Lines.Strings[I]);
  s := URL;
  if POS('http', URL) > 0 then
  begin
    delete(URL, 1, 7); //retira http:// da frente
    while Pos('/', URL) > 0 do
    S[Pos('/', S)] := '*';

    tag := Pos('*', URL);

    GETVAR := copy(URL, tag+1, length(URL)-tag+1); //pega somente o arquivo desejado, exemplo: /index.php?page=inicio
    URL := copy(URL, 1, tag-1); //pega somente o host, exemplo: www.meusite.com

    VERIFY.Active := False;
    VERIFY.Close;
    VERIFY.Host := URL;
    VERIFY.Port := 80;
    VERIFY.Socket.Unlock;
    VERIFY.Open;
    VERIFY.Active := True;
    SOCKTXT := 'GET '+GETVAR; // +' HTTP/1.0'+chr(13)+chr(10)+chr(13)+chr(10);

    //inicilizando variável para controle
    //RECEIVEDANSWER := False;

    VERIFY.Socket.SendText(SOCKTXT);

    //aguardando pela resposta ou desconexão do socket
    while VERIFY.Active do
      if VERIFY.Socket.ReceiveLength = 0 then
         showmessage('socket desconectado');
      Application.ProcessMessages;  // evita que a aplicação congele
  end;
end;

OBS: dentro do memo coloquei a seguinte URL

http:\\bovespa.com.br/bdi\bdi2711.zip

abraço

Editado por Jhonas
Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...