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

(Resolvido) Comunicação entre PCs em uma rede


Guest José Da Silva

Pergunta

Guest José Da Silva

Caros amigos,

Gostaria de controlar uma Matriz (Interface), estando vários utilizadores em rede. Na prática seria um servidor dedicado onde se encontra a Matriz ligada, e os outras estações poderiam aceder por tcp/ip e, desta forma cada um seleccionava o ponto da Matriz desejada. É possível faze-lo com Delphi? Algum exemplo?

Para terminar, uma grande abraço ao amigo Micheus,

MC

José

Moçambique

Link para o comentário
Compartilhar em outros sites

  • Respostas 69
  • Created
  • Última resposta

Top Posters For This Question

Posts Recomendados

  • 0

Boa Madrugada a todos,

Consegui resolver o problema seguindo sugestão do Micheus e organizei o código da seguinte forma:

for I:=Memo2.Lines.Count-1 downto 0 do

if Memo2.Lines.IndexOf(Copy(ReceivedCmd, 10, Length(ReceivedCmd))) = -1 then

if Pos('Cliente1', ReceivedCmd) = 1  then

  begin

  Memo2.Lines.Delete(0);

   Memo2.Lines.Insert(0,Copy(ReceivedCmd, 10, Length(ReceivedCmd)));

  end;

  if Memo2.Lines.IndexOf(Copy(ReceivedCmd, 10, Length(ReceivedCmd))) = -1 then

if Pos('Cliente2', ReceivedCmd) = 1 then

  begin

   Memo2.Lines.Delete(1);

   Memo2.Lines.Insert(1,Copy(ReceivedCmd, 10, Length(ReceivedCmd)));

  end;

Desta forma fixo os strings em determinada linha. Para já funciona com dois Clientes... Vou tentar evoluir para os 8 Clientes e, logo deixarei o meu testemunho.

José,

O Africano

Link para o comentário
Compartilhar em outros sites

  • 0

Boa Noite Companheiros,

Resolvido o problema de comparação. Resta agora solucionar o problema dos valores Hexadecimais nos Tmemo, TLbox.... Entretanto fica o código enquanto irei testa-lo mais amiude por forma a descobrir possíveis bugs.

O código:

for I:=Memo2.Lines.Count-1 downto 0 do //a propriedade Count retorna o nº de linhas


if Memo2.Lines.IndexOf(Copy(ReceivedCmd, 10, Length(ReceivedCmd))) = -1 then //evito que repita no Memo os mesmos strings

if Pos('Cliente1', ReceivedCmd) = 1  then   //selecciono o Cliente

  begin
     Memo2.Lines.Delete(0);  //forço o delete na Linha 1ª
     Memo2.Lines.Insert(0,Copy(ReceivedCmd, 10, Length(ReceivedCmd)));//insiro directamente na linha1ª
     ListBox1.Items.Add(Copy(ReceivedCmd, 10, Length(ReceivedCmd)));// Crio um delay com o Timer para ser enviado via socket para Matriz
     ListBox1.ItemIndex := ListBox1.Count -0;

  end;

Ate amanha

José

Link para o comentário
Compartilhar em outros sites

  • 0

José, referente aos dois últimos posts seus, experimente colocar este código na sua procedure.

Basicamente, o que fiz foi desmenbrar sua string de comando para variáveis locais, as quais facilitarão muito o processo.

Apesar de não saber qual a composição da sua string de comando eu tentei fazer uso do que você já deixa meio claro nos exemplos. Assim, assumo que os 9 caracteres iniciais correspondem a identificação do client e o restante como comando.

Da itendificação do client, eu assumo que você padronizou o nome como "Cliente" + Índice. Assim, desta identificação, extraimos o índice do client que nos dá acesso direto a posição em qualquer tipo de lista que você utilize para corresponder às informações do mesmo - como é o caso da linha no memo2.

Observe que o uso de Memo2.Lines.IndexOf retorna a existência de uma string (no caso a de comando) em qualquer uma das linhas, logo não é necessário loop para esta verificação - ou existe, ou não existe.

procedure ....
var
  ClientSource,
  ClientCommand :String;
  ClientIndex :Integer;
begin
  ClientSource := Trim(Copy(ReceivedCmd, 1, 9));  // copia o "nome" (identificação) do cliente
  ClientIndex := StrToInt(Copy(ClientSource, 8, Length(ClientSource))); // copia o "número" (índice) do cliente
  ClientCommand := Copy(ReceivedCmd, 10, Length(ReceivedCmd));  // copia apenas o comando enviado pelo cliente

  if Memo2.Lines.IndexOf(ClientCommand) = -1 then  // comando não repetido
  begin
    Memo2.Lines.Delete(ClientIndex);
    Memo2.Lines.Insert(ClientIndex, ClientCommand);
  end;
  ...  // outros procedimentos
end;

Quanto a questão do hexadecimal, acredito que a questão estaria relacionada a string de comando. Acredito que ela já esteja sendo enviada no formato a ser enviado para a porta, ou seja, com os caracteres de configuração. Se for isto, então, para que você mostre o comando no formato hexa legível (vamos dizer assim), você teria que implementar uma rotina que faça o inverso, ou seja, converta cada caracter da string de comando (apenas a parte do comando) em seu código decimal que formatado em hexa resultará no formato legível. Seria fazendo uso da função CharsToHexa (deste post).

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Boa Tarde a todos, Viva Micheus,

Só poderei testar o seu código logo mais. Neste momento não tenho aqui o Delphi. Quanto ao valor Hexa , o problema é que nem sequer aparece no TMemo2, muito menos no TListBox1. Assim, já não existe envio de nada porque se não houver comparação, de acordo com o algoritmo, não envia para a ListBox1. No TMemo1 ainda aparece em formato Char....

P.S. a minha string para alem da identificação 'Cliente1,...,n' vem a seguir (ou supostamente deveria vir), o Valor ex:AA55030201 em Hexa....

Aquele abraço

José

Link para o comentário
Compartilhar em outros sites

  • 0
P.S. a minha string para alem da identificação 'Cliente1,...,n' vem a seguir (ou supostamente deveria vir), o Valor ex:AA55030201 em Hexa....

para facilitar, você poderia colocar a formatação desta string, tipo:

0-9 = identificação cliente (ex: Cliente<idx>

10-20 = comando (ex: CMDxx)

21-30 = valor hexadecimal (ex: AA55030201)

também, acho que seria útil, visualizar o código que faz a formatação e o envio desta string pelos Clients, e do lado do Server, o código que processa este recebimento. Assim, acredito que ficaria mais fácil ter uma idéia melhor sobre a questão.

Abraços.

Link para o comentário
Compartilhar em outros sites

  • 0

Ola Micheus,

Boa Noite Companheiros,

Tentei o teu código e de facto condensou bastante o nº de linhas. Valeu!

Quanto ao hexa é que ta complicando. Já tentei outras forma e o resultado é :"Is not a valid Integer Value"!!

Vou lutando para ver no que dá...

Obrigadão Micheus...

José

Link para o comentário
Compartilhar em outros sites

  • 0

Boa Noite Companheiros,

Viva Micheus,

Do Lado do Cliente o código que envia o Valor Hexa:

ClientSocket1.Socket.SendText(#$AA#$55#$03#$07#$1F); {Aqui é o comando em Hexa}

//e

ClientSocket1.Socket.SendText(Format('%s %s',[ComboBox1.Text, Edit1.Text])); {Aqui eu recebo o nº de cliente do ComboBox1 e, do Edit1 qualquer comando (sem ser em Hexa) que
                                                                                                                        queira enviar}
Do lado do Servidor Recebo:
var

  ReceivedCmd :String;
  HexaValue:String;        {As variáveis}


(*...*)

  ReceivedCmd:= CharsToHexa(Socket.ReceiveText); {Tento converter para Hexa através desta função CharsToHexa. Originalmente estava ReceivedCmd:= Socket.ReceiveText; }

  HexaValue := Copy(ReceivedCmd, 10, Length(ReceivedCmd));


  Memo1.Lines.Add(Format('De: %s > %s', [Socket.RemoteAddress, ReceivedCmd])); {porque usei anteriormente função já consigo receber o valor em Hexa, e o IP do Cliente}  

  Memo1.SelStart:= Length(Memo1.Lines.Text);

//...

     ListBox1.Items.Add(Copy(ReceivedCmd, 10, Length(ReceivedCmd)));  {Adiciono o Comando neste ListBox1 onde sera posteriormente enviado }
     ListBox1.ItemIndex := ListBox1.Count -0;

//...

     Setup.ComPort1.WriteStr(ListBox1.Items.Text); {Aqui envio via porta 232 para a Matriz}

A questão agora esta no facto de, se eu utilizar o ReceivedCmd:= CharsToHexa(Socket.ReceiveText); perco o Identificação CLIENTE(n) mas recebo os valores em Hexa no TMemo. Só que tem um problema - o servidor fica sem funcionar de acordo com o projectado

.

Se retiro CharToHexa - ReceivedCmd:= Socket.ReceiveText; - Funciona tudo bem mas sem valores Hexadecimais...!?!? Não existe uma forma de eu separar a string de forma que eu tenha a Identificação do Cliente e simultaneamente o valor Hexa?

Aquele abraço e obrigado pela paciência...

José

Link para o comentário
Compartilhar em outros sites

  • 0
A questão agora esta no facto de, se eu utilizar o ReceivedCmd:= CharsToHexa(Socket.ReceiveText); perco o Identificação CLIENTE(n) mas recebo os valores em Hexa no TMemo. Só que tem um problema - o servidor fica sem funcionar de acordo com o projectado

.

Se retiro CharToHexa - ReceivedCmd:= Socket.ReceiveText; - Funciona tudo bem mas sem valores Hexadecimais...!?!?

Não existe uma forma de eu separar a string de forma que eu tenha a Identificação do Cliente e simultaneamente o valor Hexa?

Acho que agora conseguiremos avançar mais, então penso que tem uma forma sim!

Vamos lá...

Do Lado do Cliente o código que envia o Valor Hexa:

ClientSocket1.Socket.SendText(#$AA#$55#$03#$07#$1F); {Aqui é o comando em Hexa}
//e
ClientSocket1.Socket.SendText(Format('%s %s',[ComboBox1.Text, Edit1.Text])); {Aqui eu recebo o nº de cliente do ComboBox1 e, do Edit1 qualquer comando (sem ser em Hexa) que queira enviar}
Se o código no lado do Client está assim mesmo, então fica complicado ao receber no lado do Server. O ideal é que a informação chegue completa, ou seja, todos os campos de uma só vez (enviadas com um único SendText), assim ela é processada em uma única string (quando processada ReceiveText). Padronizando o formato da mensagem a ser enviada, teremos facilidade no seu recebimento e interpretação. Eu não estou certo de que sempre será enviado nesta sequência (Identificação Client, Comando diverso, Comando Hexa), mas vou supor que sim, então vamos tentar algo assim:
procedure ...
var
  CmdHexa :string;
begin
  CmdHexa := #$AA#$55#$03#$07#$1F; // imagino que este valor fixo seja apenas para teste, 
                                   // então fica conveniente colocá-lo em uma variável
                                   // e a string legível poderá conter caracteres "estranhos"
  ClientSocket1.Socket.SendText(Format('%s|%s|%s',[ComboBox1.Text, Edit1.Text, CmdHexa]));
end;
o que estamos fazendo é utilizar o caracter "|" como delimitador de campo. Assim, termos os três campos bem definidos. Há viabilidade até de algum dos campos ficarem nulos, sem gerar problemas.
Do lado do Servidor Recebo:
var
  ReceivedCmd :String;
  HexaValue:String;        {As variáveis}
begin
(*...*)

  ReceivedCmd:= CharsToHexa(Socket.ReceiveText); {Tento converter para Hexa através desta função CharsToHexa. Originalmente estava ReceivedCmd:= Socket.ReceiveText; }

  HexaValue := Copy(ReceivedCmd, 10, Length(ReceivedCmd));
  Memo1.Lines.Add(Format('De: %s > %s', [Socket.RemoteAddress, ReceivedCmd])); {porque usei anteriormente função já consigo receber o valor em Hexa, e o IP do Cliente}  
  Memo1.SelStart:= Length(Memo1.Lines.Text);
 //...
  ListBox1.Items.Add(Copy(ReceivedCmd, 10, Length(ReceivedCmd)));  {Adiciono o Comando neste ListBox1 ond sera posteriormente enviado }
  ListBox1.ItemIndex := ListBox1.Count -0;
 //...
  Setup.ComPort1.WriteStr(ListBox1.Items.Text); {Aqui envio via porta 232 para a Matriz}
Da forma como estava sendo enviada a mensagem pelo Client (uma sequencia Hexa e outra com identificação/comando) ficaria mais complicado manipular a informação recebida pelo Server. Com a formatação proposta, teremos facilidade em tratar a mensagem recebida, com exemplificado:
var
  ClientId,
  HexaValue,
  ReceivedCmd,
  ReceivedMsg :String;
  DelimiterIdx :Integer;
begin
  ReceivedMsg := Socket.ReceiveText;
 // retiramos o primeiro campo: Identificação
  DelimiterIdx := Pos('|', ReceivedMsg);
  ClientId := Copy(ReceivedMsg, 1, DelimiterIdx -1);
  Delete(ReceivedMsg, 1, DelimiterIdx);

 // retiramos o segundo campo: Comando diverso
  DelimiterIdx := Pos('|', ReceivedMsg);
  ReceivedCmd := Copy(ReceivedMsg, 1, DelimiterIdx -1);
  Delete(ReceivedMsg, 1, DelimiterIdx);

 // o que sobra é o terceiro campo: Comando Hexa
  HexaValue := CharsToHexa(ReceivedMsg);  // será o texto legível que no caso do exemplo anterior
                                          // irá conter o texto "$AA$55$03$07$1F", enquanto que
                                          //  o texto recebido seria visualizado como "ªU□□□"
                                          // (se não me engano) que deve ser o texto em
                                          // ReceivedMsg neste ponto do código
  Memo1.Lines.Add(Format('De: %s > %s %s', [Socket.RemoteAddress, ReceivedCmd, HexaValue])); 
  Memo1.SelStart:= Length(Memo1.Lines.Text);
 //...
  ListBox1.ItemIndex := ListBox1.Items.Add(ReceivedCmd);
 //...
  Setup.ComPort1.WriteStr(ListBox1.Items.Text);
end;

É apenas uma adaptação do que você postou. Espero que você capte o espírito da coisa e o adeque a seu código.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Ola Micheus,

Estou sem Delphi neste momento. Mas logo a noite irei testar a ideia. De facto faz mais sentido como você desenhou o código. Eu tinha tentado algo parecido (muito pouco parecido, convenhamos), só que ele convertia a identificação Cliente(n) em Hexa..!?

Aquele abraço,

José

Link para o comentário
Compartilhar em outros sites

  • 0

Olá Micheus,

Boa Noite companheiros,

É... de facto as coisas estão a compor-se. Com o código que me mandastes, para além de simplificar demasiado os processos, revela grande conhecimento da tua parte. Neste momento, tenho de reconhecer que nada sei... mas espero um dia conseguir pelo menos fazer um "mano-a-mano" contigo, como se diz por cá!

Para além de só apanhar em tutorias coisas que servem para pouca coisa, reconheço a minha ignorância!

- Tive que fazer algumas alterações, naturalmente, mas como tu dizias, valeu o espírito da coisa.

Amanha vou fazer testes a procura de bugs, e logo, logo posto o código ou....espero que não! , algumas dúvidas.

Aquele abraço

José

O Africano

Link para o comentário
Compartilhar em outros sites

  • 0

Boa Noite a todos,

Ola Micheus,

Estou tentando resolver um pequeno problema na implementação do código. Quando envio uma string em hexa ex:#$AA#$55#$03#$00#$1F, ele elimina os zeros aparentemente usando a função ChatToHExa. Pensei que fosse este o problema, mas ao enviar para Matriz nem sequer uso a função. Mais grave é que no exemplo que atrás nomeei os valores #$00 são completamente apagados e já não aparece o #$1F. Ora, existe um comando onde precisamente uso #$00. Liguei para monitorar um soft. 232 Hexa Com Tool, e verifiquei que ele volta (ou existe e não aparece!!??), dizia, ele volta a adicionar os zeros em falta, menos quando a situação é #$00, onde ele elimina de facto o #$00 e o restante #$1F, ficando apenas AA5503. Isso faz com o comando perca efectividade, ou seja a Matriz não reage.

Outra situação é que, por algum motivo quando os valores a enviar são nulos, ou seja , em branco, no soft. de monitorização aparece em hexa sempre 0D0A ???. No caso anterior como ele elimina o último byte to string , aparece apenas AA5503 e o restante 0D0A!!??

Atenção: Isso tudo é quando uso o servidor. Ou seja, o Cliente envia para o Server e o Server através de 232 para a Matriz. Se envio directamente para a Matriz via 232 nada disso acontece.

Entretanto, estou dando volta a tudo que é possível, procurando entender...

Aquele abraço

José

Link para o comentário
Compartilhar em outros sites

  • 0
Mais grave é que no exemplo que atrás nomeei os valores #$00 são completamente apagados e já não aparece o #$1F. Ora, existe um comando onde precisamente uso #$00.
e está correto. Lembre-se que o tipo string longo equivale a um PChar e é terminado por um zero.

Talvez uma opção seja enviar para o servidor o "string hexa" não o valor dos caracteres.

Deixa ver se consigo explicar melhor. Quando você monta deste modo #$1F, é a mesma coisa que você estivesse colocando #31, ou seja você está tratando de caracteres. Minha sugestão é que você trate o valor como string: '$1F'. Deste modo, a string que você citou ficaria assim: '$AA$55$03$00$1F'.

Uma alternativa a isto, deveria ser o uso de Stream para troca de dados, ao invés de SendText/ReceiveText. Mas, penso que teriam que ser implementados mais controles.

mas, continuando...

Depois, na hora de enviar para a porta, você retira cada numero hexa da string e o converte para caracter novamente e o envia em seqüência para a porta. Acho que deve funcionar.

Outra situação é que, por algum motivo quando os valores a enviar são nulos, ou seja , em branco, no soft. de monitorização aparece em hexa sempre 0D0A ???.
este par corresponde a "nova linha" (#13#10). Por acaso você está enviando de algum lugar, ou está pegando o texto de um Memo vazio? Deve ser por aí o problema.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Boa Tarde Companheiros,

Viva Micheus,

Você quer dizer algo do género:

HexaConv:= (ReceivedCmd);   //onde ReceivedCmd são os comandos '$AA$55$03$00$1F'

    HexaConv:= AnsiReplaceStr(HexaConv, '$', '#$'); //Onde Existe o '$' substituo por '#$'

Desta forma eu posso armazenar numa variável HexaConv a String e depois envio através do Setup.ComPort1.WriteStr...Esta é ideia??

Aquele abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Olá Micheus,

Acho que entendi a sua ideia agora, mas não estou conseguindo implementa-la.

Consigo receber a srting $AA$55$03$00$1F, e guarda-la numa variável . Acontece porem quando tento enviar - e aqui o Delphizinho trata de converter as coisas e depois já não sei a quantas ando -, ao monta-lo no Setup.ComPort1.WriteStr();, ele simplesmente volta a converter em Hexa e estraga tudo. No Soft onde monitorizo a chegada dos strings , em ASCii consigo ter exactamente a string que mando , inclusive com os respectivos '$'...

Do lado do Cliente usei uma variável x:='$AA$55$03$00$1F'; e depois despejei no ClientSocket1.Socket.SendText(x);

P.S. Depois de analise ao componente verifico uqe cada vez que envio um comando para o hardware, ex: $AA$55...$1F, de forma a que o hardware o interprete , o que na verdade enviamos é um Cha(x). Talvez a solução passasse por modificar para Char o comando a enviar antes de o faze-lo. O facto é que não consigo ate o momento uma função que trabalhe em condições.

Aquele abraço

José

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

  • 0
Do lado do Cliente usei uma variável x:='$AA$55$03$00$1F'; e depois despejei no ClientSocket1.Socket.SendText(x);
José, era isto que falava sim.

Mas do lado do server, você deverá desmembrar esta seqüência em "trios" de caracteres, onde cada um corresponde a um valor hexa da seqüência enviada.

pegando carona naquele exemplo que postei anteriormente (post#36), poderia ser assim:

var
  ...
  CharHexaStr :string;
begin
  ...

 // esta linha abaixo foi modificada em relação ao post inicial
  HexaValue := ReceivedMsg;  // será o texto legível que no caso do exemplo anterior
                                          // irá conter o texto "$AA$55$03$07$1F", enquanto que
                                          //  o texto recebido seria visualizado como "ªU□□□"
                                          // (se não me engano) que deve ser o texto em
                                          // ReceivedMsg neste ponto do código

  Memo1.Lines.Add(Format('De: %s > %s %s', [Socket.RemoteAddress, ReceivedCmd, HexaValue]));
  Memo1.SelStart:= Length(Memo1.Lines.Text);
//...
  ListBox1.ItemIndex := ListBox1.Items.Add(ReceivedCmd);
//...
  Setup.ComPort1.WriteStr(ListBox1.Items.Text);

// aqui começa a nova implementação 
// pelas minhas contas, após o envio do comando, 
// você está enviando os valores Hexa 
  while HexaValue <> '' do
  begin
    CharHexaStr := Copy(HexaValue, 1, 3); // copia primeiro trio da seqüência
    Delete(HexaValue, 1, 3);  // elimina o primeiro trio da seqüência
    Setup.ComPort1.WriteStr(Char(StrToInt(CharHexaStr))); // envia código no formato char
  end;
  ...
end;
Esta idéia pressupõe: - que a string hexa contenha sempre 3 caractere para representar o valor - no formato $FF; - que os caracteres são válidos, ou seja, números (0..9) e letras (A..F); se por acaso o envio para a porta estiver incorreto, ou seja, esteja indo algum lixo junto, então experimente torna-lo um string concatenando um caracter nulo: Setup.ComPort1.WriteStr(Char(StrToInt(CharHexaStr)) +#0); há ainda a possibilidade de enviar tudo de uma vez, "bufferizado".
var
  ...
  CmdBuffer :array[1..5] of char;
  CmdBufferLen :Integer;
  CharHexaStr :string;
begin
  ...

  CmdBufferLen := 0;
  while HexaValue <> '' do
  begin
    CharHexaStr := Copy(HexaValue, 1, 3); // copia primeiro trio da seqüência
    Delete(HexaValue, 1, 3);  // elimina o primeiro trio da seqüência
    Inc(CmdBufferLen);
    CmdBuffer[CmdBufferLen] := Char(StrToInt(CharHexaStr));
  end;
  Setup.ComPort1.Write(CmdBuffer, CmdBufferLen); // envia a seqüência completa
  ...
end;

observe que utilizamos o método Write do componente ComPort, onde passamos o buffer e a quantidade de bytes a "escrever" na porta.

Tente uma das alternativas, veja o que consegue.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Olá Micheus,

Viva companheiros,

É, de facto o meu erro estava no ComPort1.WriteStr(); , para alem de outros, naturalmente. Com o ComPort.Write(); funciona bem. Optei por usar

possibilidade de enviar tudo de uma vez, "bufferizado".

Neste momento estou refazendo o código todo, já que foi implementada uma nova forma de enviar os Comandos. Para já funciona beleza...

Resta tratar algumas excepções e testar de novo. A ideia é a partir do servidor controlar a aplicação. Ainda algum trabalho pela frente.

Valeu Micheus, tu sabe da coisa! Um dia vou convidar-te para sentarmos aqui em Moçambique debaixo de um coqueiro bebendo leite de coco enquanto miramos a paisagem... sem Delphi na cabeça!

Aquele abraço

José

O Africano

Link para o comentário
Compartilhar em outros sites

  • 0
ola micheUs.

tava dando uma olhanda nesses 45 posts e vi um arquivo anexo "Socket_Demo"

como é que usa? não tem extensao.

Ele tem extensão sim e é ZIP, talvez você tenha gravado sem a extensão. De qualquer modo, você pode baixar ele do link 4Share ali abaixo na minha assinatura (vá em Programacao\Sockets)

Link para o comentário
Compartilhar em outros sites

  • 0

Boa Noite companheiros,

Ola Micheus,

Só hoje pude pegar na aplicação por motivos profissionais. O servidor já esta pronto e apenas falta tratar algumas excepções. Entretanto, e porque tracei uma estratégia para trabalhar o problema que consiste em não permitir que haja mais do que um cliente no mesmo source e destination, que passa pela condição de não haver duplicação de comandos. Poderia eventualmente, e se calhar seria mais fácil, optar por uma base de dados com uma tabela e alguns campos onde estaria os valores chaves dos comandos. Mas como prefiro uma boa luta, enveredei por exercício mais moroso e didáctico.

Algumas dúvidas subsistem ainda:

Tenho um form Setup, do lado do cliente onde configura-se o IP do servidor o nº de cliente e a ligação. Assim, o componente ClienteSocket, esta neste unit.

Mas no Main Form preciso de estar a receber os eventos da rede, ou seja, os comandos que estão a ser reenviados pelo servidor ($AA$...$nn), do género:

procedure TForm1.ClientSocket1Read(Sender: TObject;  Socket: TCustomWinSocket);
Acontece porem que este procedimento só funciona no Unit onde esta o componente ClienteSocket, que no meu caso esta no Form Setup. Como chama-lo para que no Main form eu possa estar a receber sempre os comandos reenviados pelo Servidor? Do género:
procedure TForm1.ClientSocket1Read(Sender: TObject;   Socket: TCustomWinSocket);
var
  ReceivedCmd :String;
begin
 // armazena na variável o texto recebido
  ReceivedCmd := Socket.ReceiveText;
 // mostra quem enviou e o texto no memo
  Memo1.Lines.Add(Format('from: %s > %s', [Socket.RemoteAddress, ReceivedCmd]));
end;

Qualquer ajuda é bem vinda.

Aquele Abraço

José

Link para o comentário
Compartilhar em outros sites

  • 0
Tenho um form Setup, do lado do cliente onde configura-se o IP do servidor o nº de cliente e a ligação. Assim, o componente ClienteSocket, esta neste unit.

Mas no Main Form preciso de estar a receber os eventos da rede, ou seja, os comandos que estão a ser reenviados pelo servidor ($AA$...$nn), do género:

procedure TForm1.ClientSocket1Read(Sender: TObject;  Socket: TCustomWinSocket);
Acontece porem que este procedimento só funciona no Unit onde esta o componente ClienteSocket, que no meu caso esta no Form Setup. Como chama-lo para que no Main form eu possa estar a receber sempre os comandos reenviados pelo Servidor? Do género:
procedure TForm1.ClientSocket1Read(Sender: TObject;   Socket: TCustomWinSocket);
var
  ReceivedCmd :String;
begin
 // armazena na variável o texto recebido
  ReceivedCmd := Socket.ReceiveText;
 // mostra quem enviou e o texto no memo
  Memo1.Lines.Add(Format('from: %s > %s', [Socket.RemoteAddress, ReceivedCmd]));
end;
José, mas será que realmente é necessário que o componente socket fique neste form? Não seria mais prático mantê-lo no principal, já que existirá durante toda a aplicação e lá você acessará as informações? Mas, sendo necessário esta situação, há sim como você passar o evento para o forma principal. A forma que acredito seja a mais simples e de fácil compreensão seria criar o procedimento no seu form principal e chamá-lo do evento que está na outra unit. Vamos ver ser consigo explicar melhor. Supondo este form onde está o componente socket1, então você faria o seguinte: - copia o cabeçalho do procedimento que trata o evento para o seu form principal; - no form principal, você coloca todo o código que estava no evento que está na outra unit; - de volta à outra unit, recorta o código e cola no procedimento que você criou no form principal e coloca em seu lugar a chamada para aquele procedimento; No Form Principal:
uses
  Windows, Messages, ..., Sockets;
type
  TFormPrincipal = class(TForm)
    ...
  public
    TFormPrincipal.ClientSocket1Read(Sender: TObject;   Socket: TCustomWinSocket);
  end;
...
implementation

procedure TFormPrincipal.ClientSocket1Read(Sender: TObject;   Socket: TCustomWinSocket);
var
  ReceivedCmd :String;
begin
  ReceivedCmd := Socket.ReceiveText;
  Memo1.Lines.Add(Format('from: %s > %s', [Socket.RemoteAddress, ReceivedCmd]));
end;
...
No form de configuração onde está o componente:
...
implementation
uses
  uFormPrincipal;  
// a unit do form principal deve ser declarado na USES após o IMPLEMENTATION para
// evitar o erro de compilação ref. à referência circular. Isto porque provavelmente
// na unit do form principal, você faz referência à unit do form de configuração

procedure TForm1.ClientSocket1Read(Sender: TObject;   Socket: TCustomWinSocket);
begin
  FormPrincipal.ClientSocket1Read(Sender, Socket);
end;
...

Veja se consegue compreender.

Abraços

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...