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

Olá Micheus,

Só para calcinar as ideias:

No Form Principal:

uses
  Windows, Messages, ..., Sockets;
type
  TFormPrincipal = class(TForm)
    ...
  public
    TFormPrincipal.ClientSocket1Read(Sender: TObject;   Socket: TCustomWinSocket);
Aqui da uma mão cheia de erros!! - ',' or ':' expected but '.' found ... e por aí fora... No form de configuração onde está o componente:
...
implementation
uses
  uFormPrincipal;  //[b]
Aqui será FormPrincipal ou apenas unit1? Porque se deixo o MS8 ele pede MS8.dcu!! - a propósito é mesmo 'u....MS8'? Atenção que o meu Form Principal se chama TMS8. Alguma coisa esta falhando...
procedure TForm1.ClientSocket1Read(Sender: TObject;   Socket: TCustomWinSocket);
begin
  FormPrincipal.ClientSocket1Read(Sender, Socket); 
end;
...

Eu compreendi, só que dá um monte de erros....

Abraço

Link para o comentário
Compartilhar em outros sites

  • 0
No Form Principal:

uses
  Windows, Messages, ..., Sockets;
type
  TFormPrincipal = class(TForm)
    ...
  public
    TFormPrincipal.ClientSocket1Read(Sender: TObject;   Socket: TCustomWinSocket);
Aqui da uma mão cheia de erros!! - ',' or ':' expected but '.' found ... e por aí fora...
é... :blush: Coisas do copiar/colar. Devia estar:
TFormPrincipal = class(TForm)
    ...
  public
    ClientSocket1Read(Sender: TObject;   Socket: TCustomWinSocket);

quanto ao resto, você me facilitaria se passasse o nome das units e dos forms, assim eu poderia exemplificar com algo mais realista.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Boa noite companheiros,

Viva Micheus,

Cá vai o código de acordo com a tua sugestão:

Na Unit2 (Setup)

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, CPort, StdCtrls, ExtCtrls, CPortCtl, Registry, yupack, CPDrv,
  EasyRegAdvanced, psvBasiclbl, psvBorderLabel, Buttons, OvalBtn, ScktComp;

type
  TSetup = class(TForm)
    ComPort1: TComPort;
    Button1: TButton;

//(...)por aí fora
.
.
.
.
  procedure FormCreate(Sender: TObject);
    procedure Btn3Click(Sender: TObject);
    procedure Btn1Click(Sender: TObject);
    procedure ComPortOpen(Sender: TObject);
    procedure ComPortClose(Sender: TObject);
    procedure OBtn1Click(Sender: TObject);
    procedure btnClientClick(Sender: TObject);
    procedure ClientSocket1Connect(Sender: TObject;Socket: TCustomWinSocket);
    procedure ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure AtualizaEstado(Enable :Boolean);
    procedure Button3Click(Sender: TObject);
    //procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);

  private


    { Private declarations }
   //  procedure AtualizaEstado(Enable :Boolean);

  public
    { Public declarations }
  end;

var
  Setup: TSetup;

implementation

uses Unit3, Unit1;


{$R *.dfm}

procedure TSetup.AtualizaEstado(Enable :Boolean);
begin
  //btnEnvia.Enabled := Enable;
end;


procedure TSetup.FormCreate(Sender: TObject);
.
.
.

//.... (...)

.
.
.
procedure TMS8.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);

begin
  MS8.ClientSocket1Read(Sender, Socket);
end;
... e na Unit1 (Form principal):
unit Unit1;

interface

uses
//...(...)

type



  TMS8 = class(TForm)
.
.
.
   
//...(....)....
.
.
.

    procedure LBOffClick(Sender: TObject);
    procedure LBMenuClick(Sender: TObject);
    procedure LB0Click(Sender: TObject);
    procedure LB1Click(Sender: TObject);
    procedure LB2Click(Sender: TObject);
    procedure LB3Click(Sender: TObject);
    procedure LB4Click(Sender: TObject);
    procedure LB5Click(Sender: TObject);
    procedure LB6Click(Sender: TObject);
    procedure LB7Click(Sender: TObject);
    procedure LB00Click(Sender: TObject);
    procedure BmsXPButton1Click(Sender: TObject);
    procedure LB01Click(Sender: TObject);
    procedure LB02Click(Sender: TObject);
    procedure LB03Click(Sender: TObject);
    procedure LB04Click(Sender: TObject);
    procedure LB05Click(Sender: TObject);
    procedure LB06Click(Sender: TObject);
    procedure LB07Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
    ClientSocket1Read(Sender: TObject;   Socket: TCustomWinSocket);// de acordo com o sugerido.
   end;

Const
  Header = Char($AA) +Char($55);
  Aud    = Char($02);  //audio
  Vid    = Char($01);  //video
  ViAu   = Char($03);  //video + audio
  Header1 = '$AA$55';
  Aud1    = '$02';  //audio
  Vid1    = '$01';  //video
  ViAu1   = '$03';

var
  MS8: TMS8;
  VA :Char;   //Video e/ou Audio
  VA1,
  ReceivedMsg,
  LBSource1,
  HexaId :String;
  LBSource :Char;
  StrInt,
  DelimiterIdx: Integer;
  StrString:string;
  StrChar:Char;



implementation

uses Unit2;

//uses Unit3;

{$R *.dfm}
.
.
.
//....(....)....
.
.
.
.

procedure  TMS8.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);// de acordo com a tua sugestão.

var
  ReceivedCmd :String;
begin
  ReceivedCmd := Socket.ReceiveText;

 end;

Espero que seja o suficiente para a análise em questão.

Aquele abraço

José Da Silva

Link para o comentário
Compartilhar em outros sites

  • 0

Olá Micheus,

Acabei de testar e de facto alguma coisa esta errada. Na verdade é uma data de erros:

[Warning] Unit1.pas(9): Unit 'Outline' is deprecated
[Error] Unit1.pas(170): ',' or ':' expected but '(' found
[Error] Unit1.pas(170): ',' or ')' expected but ';' found
[Error] Unit1.pas(170): 'END' expected but ')' found
[Error] Unit2.pas(67): 'TObject' is not a type identifier
[Error] Unit2.pas(76): Undeclared identifier: 'ListBox1'
[Error] Unit2.pas(76): Missing operator or semicolon
[Error] Unit2.pas(85): Missing operator or semicolon
[Error] Unit2.pas(96): 'TObject' is not a type identifier
[Error] Unit2.pas(99): Undeclared identifier: 'ComPort1'
[Error] Unit2.pas(109): Missing operator or semicolon
[Error] Unit2.pas(113): Statement expected but 'PROCEDURE' found
[Error] Unit2.pas(113): 'TObject' is not a type identifier
[Error] Unit2.pas(115): Undeclared identifier: 'Btn1'
[Error] Unit2.pas(118): 'TObject' is not a type identifier
[Error] Unit2.pas(120): Undeclared identifier: 'Btn1'
[Error] Unit2.pas(120): Operator not applicable to this operand type
[Error] Unit2.pas(121): Missing operator or semicolon
[Error] Unit2.pas(124): 'TObject' is not a type identifier
[Error] Unit2.pas(129): 'TObject' is not a type identifier
[Error] Unit2.pas(132): Undeclared identifier: 'edServerName'
[Error] Unit2.pas(132): There is no overloaded version of 'Trim' that can be called with these arguments
[Error] Unit2.pas(134): Missing operator or semicolon
[Error] Unit2.pas(138): Undeclared identifier: 'ComboBox1'
[Error] Unit2.pas(142): Missing operator or semicolon
[Error] Unit2.pas(143): Not enough actual parameters
[Error] Unit2.pas(145): Undeclared identifier: 'ClientSocket1'
[Error] Unit2.pas(145): Missing operator or semicolon
[Error] Unit2.pas(145): Missing operator or semicolon
[Error] Unit2.pas(147): Statement expected, but expression of type 'Text' found
[Error] Unit2.pas(151): '.' expected but ';' found
[Warning] Unit2.pas(152): Text after final 'END.' - ignored by compiler
[Error] Unit2.pas(29): Unsatisfied forward or external declaration: 'TSetup.Btn3Click'
[Error] Unit2.pas(35): Unsatisfied forward or external declaration: 'TSetup.ClientSocket1Connect'
[Error] Unit2.pas(36): Unsatisfied forward or external declaration: 'TSetup.ClientSocket1Disconnect'
[Error] Unit2.pas(38): Unsatisfied forward or external declaration: 'TSetup.Button3Click'
[Fatal Error] Unit1.pas(200): Could not compile used unit 'Unit2.pas

Vou tenta estudar também o que se passa...

Aquele abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Boa Tarde companheiros,

Viva Micheus,

Consegui resolver os poblemas dos erros, modificando alguns valores. Assim;

Na Unit1 (TMS8), ficou:

{ Private declarations }
  public
    { Public declarations }
    procedure ClientSocket1Read(Sender: TObject; Socket:
     TCustomWinSocket);

  end;
O procedimento;
procedure  TMS8.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);

 var
 hexaRcv: string;
 begin

  HexaRcv := Socket.ReceiveText;
  label1.Caption:=HexaRcv;  //criei este label para chekar se recebo ou não os strings

 end;
Na Unit2 (TSetup);
type
  TSetup = class(TForm)
    ComPort1: TComPort;
    Button1: TButton;
    Button2: TButton;
    ListBox1: TListBox;
    EasyRegAdvanced1: TEasyRegAdvanced;
    psvBorderLabel1: TpsvBorderLabel;
    Btn3: TButton;
    Btn1: TButton;
    OBtn1: TOvalButton;
    ClientSocket1: TClientSocket;
    edServerName: TEdit;
    psvBorderLabel2: TpsvBorderLabel;
    btnClient: TButton;
    Panel1: TPanel;
    ComboBox1: TComboBox;
    Button3: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Btn3Click(Sender: TObject);
    procedure Btn1Click(Sender: TObject);
    procedure ComPortOpen(Sender: TObject);
    procedure ComPortClose(Sender: TObject);
    procedure OBtn1Click(Sender: TObject);
    procedure btnClientClick(Sender: TObject);
    procedure ClientSocket1Connect(Sender: TObject;Socket: TCustomWinSocket);
    procedure ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure AtualizaEstado(Enable :Boolean);
    procedure Button3Click(Sender: TObject);

    procedure ClientSocket1Read(Sender: TObject; Socket:     TCustomWinSocket);// <<<--------------------------
...e o procedimento;
procedure TSetup.ClientSocket1Read(Sender: TObject;   Socket: TCustomWinSocket);

begin
  MS8.ClientSocket1Read(Sender, Socket);
end;

Só que infelizmente não recebo nada!!!! Em principio esta tudo OK....sem erros!

Abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Boa Tarde Companheiros,

Já esta detectada a falha. Infelizmente o Stress tem disso! No object inspector, eventos , OnRead esqueci-me de declarar ClientSocket1Read!! Claro que depois das respectivas alterações no código que, uma vez mais, teve a preciosa colaboração do Micheus.

Espero concluir esta última parte do código ainda hoje, onde posteriormente irei postar a parte mais importante.

Aquele Abraço!

José

O Africano

Link para o comentário
Compartilhar em outros sites

  • 0

Boa Noite companheiros,

Antes de mais, gostaria de deixar o Caso de Uso para o sistema. Assim,

Caso de Uso: Comutar Matriz de Áudio e Vídeo (caso de uso com sucesso)

Actor: Utilizador

Propósito: Comutar Matriz

Overview: O utilizador entra no Sistema, faz a ligação para o Servidor, comuta a Matriz

Tipo: Primário e Essencial

 
1 Este caso de uso começa quando é comutada a Matriz

2 Entra no sistema

4 Introduz o IP do servidor e pede a ligação ao Servidor

6 Selecciona o Áudio ou Vídeo

8 Faz a comutação

10 Da a operação por concluída

3 Pede para iniciar o cliente

5 Comprova e aceita o IP fazendo a ligação ao Servidor

7 Verifica se a selecção já existe ou não. Senão, permite a comutação

9 Aceita a Comutação.

A seguir irei postar parte mais significativa do código. Infelizmente não consigo criar uma tabela de forma a estar alinhada. Se os moderadores conseguírem - perfeito! Mas acho que da para ver.

Aquele abraço

José

Editado por Micheus
Adicionada tabela.
Link para o comentário
Compartilhar em outros sites

  • 0

Boa Noite Companheiros,

Ola Micheus,

Depois de resolver alguns Bugs no programa, mais de ordem de requisitos do que propriamente de instrução, resolvi postar as partes mais importantes, considerando como satisfeito.

Se repararam no Caso de Uso, a aplicação cumpre na totalidade com o objectivo proposto. As maiores dificuldades, para alem do Stress, passa pelo desconhecimento ou falta de informação importante a nível de função e mesmo de instruções e procedimentos. Naturalmente que estes handicaps foram ultrapassados com a ajuda incomensurável do fórum, sem deixar de dar uma palavra de apreço e em particular ao Micheus pelo seu voluntarismo e pedagogismo. Um bem-haja por isso!

Devo lembrar que, na falta de soluções a nível de sintaxe e instrução, recorre-se ao poder da imaginação - afinal tão prezada pelo Einstein! Poderá não ser a forma mais bonita, mas de momento é a que funciona.

Assim:

procedure TForm1.btnServerClick(Sender: TObject);
begin
  ServerSocket1.Active := not ServerSocket1.Active;
  if ServerSocket1.Active then
  begin
    btnServer.Caption := 'Stop Server';
  end
  else
  begin
    btnServer.Caption := 'Start Server';

   // ao parar o server, as conexões ficam inválidas - limpamos a lista deixando apenas 1ª opção
    while ComboBox1.Items.Count > 1 do
      ComboBox1.Items.Delete(1);

    AtualizaEstado(False);
  end;
end;

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
 // adiciona conexão à lista

  ComboBox1.Items.AddObject(Socket.RemoteAddress, Socket);
  AtualizaEstado(True);

  // envia mensagem de conexão aceite, para o socket que conectou-se
  //Socket.SendText('Conexão aceite');

  Socket.SendText(LBox1.Items.Text);  //envia comandos existentes para actualização do cliente que iniciaram agora.
  sleep(1000);  //cria uma pausa de 1seg de forma a que os comandos possam se recebidos em condições, caso contrario devido
  Socket.SendText(LBox2.Items.Text);//a problemas de velocidade os Clientes não iriam receber e interpretar em tempo.
  sleep(1000);
  Socket.SendText(LBox3.Items.Text);
  sleep(1000);
  Socket.SendText(LBox4.Items.Text);
  sleep(1000);
  Socket.SendText(LBox5.Items.Text);
  sleep(1000);
  Socket.SendText(LBox6.Items.Text);
  sleep(1000);
  Socket.SendText(LBox7.Items.Text);
  sleep(1000);
  Socket.SendText(LBox8.Items.Text);
end;
Neste segundo trexo, permite-nos enviar mensagem aos Clientes:
procedure TForm1.btnEnviaClick(Sender: TObject);
var
  Idx :Integer;
begin

 // envia texto para clients
  if ComboBox1.ItemIndex = 0 then  // envia para todos client's conectados
  begin
   // para cada Client - Socket está em ComboBox1.Items.Objects[<indice>]
    for Idx := 1 to ComboBox1.Items.Count -1 do
      (ComboBox1.Items.Objects[Idx] as TCustomWinSocket).SendText(Edit1.Text);
  end
  else  // envia para Client selecionado - Socket está em ComboBox1.Items.Objects[<indice>]
    (ComboBox1.Items.Objects[ComboBox1.ItemIndex] as TCustomWinSocket).SendText(Edit1.Text);
Aqui podemos observar a parte já comentada, onde permite dividir a string em partes de forma a reusa-la de acordo com os interesses que veremos adiante
begin
  {aramazena texto recebido em variável }

  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, 2, DelimiterIdx);

// o que sobra é o terceiro campo: Comando Hexa
  HexaValue := (ReceivedMsg);

  ContaCaracteres:=(IntToStr(AnsiLength(HexaValue)));

{ mostra quem enviou e a mensagem no memo1 }

  Memo1.Lines.Add(Format('De: %s > %s', [Socket.RemoteAddress, HexaValue]));
  Memo1.SelStart := Length(Memo1.Lines.Text);
De uma forma imaginativa, foi resolvido o problema de adicionar os Clientes chegados e apagar os que desligam, de forma precisa. Vejam a utilização do procedimento anterior em acção.
if (Pos('Cliente1', ClientId) = 1) and (ContaCaracteres='15')then   //Serve para enviar aos recém-chegados
Begin                                                 //Clientes, de forma a actualizar as posições do grupo
  LBox1.Clear;
  LBox1.Items.Add(HexaValue); 
end;

if (Pos('Cliente1', ClientId) = 1) and (Pos('exit',HexaValue)=1) then
Begin
  LBox1.Clear;     //Apaga os comandos dos clientes que desligam
end;
Muito importante, por isso merece um espaço sozinho...
ClientIndex := StrToInt(Copy(ClientId, 8, Length(ClientId))); // copia o "número" (índice) do cliente
Aqui acredito que a imaginação é muito importante!
if Pos('exit',HexaValue)=1 then  //Arranjo encontrado para apagar Cliente quando ele se desconecta
begin
   Memo2.Lines.Delete(ClientIndex-1);
   Memo2.Lines.Insert(ClientIndex-1,ClientId+' Ausente');  // Desta forma evito 2 problemas. 1º Que ao deletar a linha
                      // a mesma seja ocupada por outro Cliente e, 2º, verifico que Clientes estão conectados

   Matrix1.Lines.Delete(ClientIndex-1);       //Apaga Cliente da Matrix(LCD) quando se desconecta
end;
Este é o coração da aplicação....
if (Memo2.Lines.IndexOf(TrimRight(Copy(HexaValue, 13, 3))) = -1 )and  //Aqui evita a repetição de comandos
     (ContaCaracteres='15')  then   //neste caso resolvo o problema dos comandos incompletos, ou seja, com
                        //menos de 15 caracteres, sejam aceites pelo Memo2. Do mesmo resolvo o Bug de
begin                     //apenas audio poder partilhar a mesma fonte que apenas Video, p.ex:

  Memo2.Lines.Delete(ClientIndex-1);
  Memo2.Lines.Insert(ClientIndex-1, TrimRight(Copy(HexaValue, 13, 3))); //selecciono uma determinada posição a direita, com n caracteres

  if ((TrimRight(Copy(HexaValue, 15, 1))<>'F')) then  //evita que os comandos que actuam apenas para
  begin
    ListBox1.ItemIndex := ListBox1.Items.Add(HexaValue);    //comutação (terminados em 'F') sejam enviados
    ListBox1.ItemIndex := ListBox1.Count -0; end;          // uma vez que do lado do cliente não é necessario

  {passamos o buffer e a quantidade de bytes a enviar na porta.}

    CmdBufferLen := 0;

    while HexaValue <> '' do
    begin
      CharHexaStr := Copy(HexaValue, 1, 3); // copia primeiro trio da sequência
      Delete(HexaValue, 1, 3);  // elimina o primeiro trio da sequência
      Inc(CmdBufferLen);
      CmdBuffer[CmdBufferLen] := Char(StrToInt(CharHexaStr));
  end;

  Setup.ComPort1.Write(CmdBuffer, CmdBufferLen); // envia a sequência completa, já bem explicada pelo Micheus
Muito importante também , porque põe os comandos em fila, com um certo delay provocado pelo Timer, e reenvia-os
{se há comandos a processar... }

  if ListBox1.Count > 0 then
  begin

//*************************envia para todos os clientes*************************

    for Idx := 1 to ComboBox1.Items.Count -1 do
      (ComboBox1.Items.Objects[Idx] as TCustomWinSocket).SendText(Listbox1.Items[0]);

    //Setup.ComPort1.WriteStr(ListBox1.Items.Text);
    ListBox1.Items.Delete(0);  { elimina comando da lista   }

end;

E tudo em relação ao Servidor...

A seguir irei postar em relação ao Cliente, no que respeita as partes modificadas pelo segundo arranjo, de forma a satisfazer as exigências do projecto. Estou receptivo a possíveis melhoramentos de código.

Até já, com os códigos alterados da parte do Cliente...

Jose

Editado por Micheus
Ajustada a identação do código. O editor do forum bagunçou a identação introduzindo tabulações.
Link para o comentário
Compartilhar em outros sites

  • 0

José, na parte em que você comentou: "//Arranjo encontrado para apagar Cliente quando ele se desconecta", acredito que você poderia fazer isto de forma mais simples se utilizar o evento ClientDisconnect. Se você observar aquele exemplo inicial que postei, nele o servidor retira da lista (listbox de clients) o client que desconectou-se.

você também deverá preocupar-se, nos clients, com quando o Server "sair do ar". Pode ocorrer de o server ser encerrado ou o micro onde ele roda, ser reiniciado. Inclusive se esta for uma situação crítica para o processamento das informações recebidas, aconselho você a avaliar o uso de uma tabela em banco de dados, ou mesmo uma coisa bem leve como um simples arquivo atualizado pelo Server.

Abraços

p.s. José, tomei a liberdade de editar seu código, ajustando a identação para facilitar a visualização/leitura das estruturas.

Link para o comentário
Compartilhar em outros sites

  • 0

Boa Noite a todos,

Na parte modificada do cliente, se bem se lembram, houve a necessidade de enviar os strings do comando de uma outra forma.

Assim, as modificações ao código inicial são:

Serve para implementar de forma a fazer o switch dos leds da Matriz e de seleccionar a Source.

Hexa3:='$AA$55$03$03$1F';
  If not LB3.StateOn and
     LBV.StateOn or LBA.StateOn then
    Setup.ClientSocket1.Socket.SendText(Format('%s|%s',[Setup.ComboBox1.Text,Hexa3]));

end;
A seguir o código do comando a enviar com a selecção do Source e Destination
Hexa0:=(Header1+VA1+LBSource1+'$00');

If not LB00.StateOn and
   (LBV.StateOn  or
    LBA.StateOn ) then
  begin   {soluciona o problema do botão acionar o comando com o LED off}
    Setup.ClientSocket1.Socket.SendText(Format('%s|%s',[Setup.ComboBox1.Text,Hexa0])); // reparem que foi trabalhado a String de forma a ser enviado para o servidor.
  end;                                                                                            end;
Aqui outro pormenor da alteração de forma a receber os hexas '$n'
if LB0.StateOn then  // só haverá um LBx na posição StateOn
begin
  LBSource1:='$00';
 // LBSource := #00; // A solução inicial que foi posta de parte
end
else
Aqui permite controlar a informação nos LCD's alfanuméricos; Reparem no procedimento importando de uma outra Unit.
public
  { Public declarations }
  procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);

..........
..........
..........

procedure  TMS8.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);

  HexaRcv := Socket.ReceiveText;

  ViAu1:=TrimRight(Copy(HexaRcv, 9, 1)); //Valor do comando Áudio/Vídeo
  LBS:=  TrimRight(Copy(HexaRcv, 12, 1));//Valores dos alfanuméricos
  LCDValue:=TrimRight(Copy(HexaRcv, 15, 1));   //  Valor da posição dos alfanuméricos
  //  Label1.Caption:=HexaRcv;

  If (ViAu1='3') and (LCDValue='0') then
  begin
    LCD02.Indicatorstring := LBS;
    LCD2.Indicatorstring := LBS;
  end
  else
  begin
    If (ViAu1='2') and (LCDValue='0') then
      LCD02.Indicatorstring := LBS
    else
    begin
      If (ViAu1='1') and (LCDValue='0') then
      begin
        LCD2.Indicatorstring := LBS; 
      end;
    end; 
  end;
Por último o procedimento na outra Unit que sera chamado na anterior
type
....
....
....
   procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);

.....
.....
.....

procedure TSetup.ClientSocket1Read(Sender: TObject;  Socket: TCustomWinSocket);
begin
  MS8.ClientSocket1Read(Sender, Socket);
end;

clientenq6.th.jpg

servidorpa6.th.jpg

Tem de haver uma forma de por estas imagens maiores...!!??

Bem, foi um projecto interessante que contou com a colaboração de todos!

Fico, como já disse receptivo a qualquer melhoria a nível de reorganização do código.

P.S. Micheus, como a utilização é para o momento - do género faz-se a sessão e depois no outro dia começa tudo de novo -,logo não achei muito importante. Aliás, ficaria bem mais fácil faze-lo através de uma base de dados.

José, na parte em que você comentou: "//Arranjo encontrado para apagar Cliente quando ele se desconecta", acredito que você poderia fazer isto de forma mais simples se utilizar o evento ClientDisconnect. Se você observar aquele exemplo inicial que postei, nele o servidor retira da lista (listbox de clients) o client que desconectou-se.

Acontece que naquele exemplo, basta desconectar um Cliente e ele desconecta todos. Logo, os Clientes todos são desligados.... não consegui implementar!

Abraço

José

Editado por jxfdasilva
Ajustando a identação, bagunçada pelo editor do forum, para facilitar a visualização/leitura das estruturas
Link para o comentário
Compartilhar em outros sites

  • 0
Tem de haver uma forma de por estas imagens maiores...!!??
José, se for importante serem maiores, me envie elas que verifico a possibilidade de anexá-las ao seu post. (é que aqui onde estou elas são bloqueadas e eu não as vejo) ;)

José, na parte em que você comentou: "//Arranjo encontrado para apagar Cliente quando ele se desconecta", acredito que você poderia fazer isto de forma mais simples se utilizar o evento ClientDisconnect. Se você observar aquele exemplo inicial que postei, nele o servidor retira da lista (listbox de clients) o client que desconectou-se.

Acontece que naquele exemplo, basta desconectar um Cliente e ele desconecta todos. Logo, os Clientes todos são desligados.... não consegui implementar!

Bom, então tem algum errinho que não percebi. Verificarei e logo que puder lhe informo.

Abraço

Link para o comentário
Compartilhar em outros sites

  • 0
José, na parte em que você comentou: "//Arranjo encontrado para apagar Cliente quando ele se desconecta", acredito que você poderia fazer isto de forma mais simples se utilizar o evento ClientDisconnect. Se você observar aquele exemplo inicial que postei, nele o servidor retira da lista (listbox de clients) o client que desconectou-se.

Acontece que naquele exemplo, basta desconectar um Cliente e ele desconecta todos. Logo, os Clientes todos são desligados.... não consegui implementar!

Bom, então tem algum errinho que não percebi. Verificarei e logo que puder lhe informo.

José, eu já corrigi o demo anexo ao tópico.

Era coisa simples. Ocorreu que inicialmente eu testava apenas usando Server e 1 Client, depois adaptei e não percebi que havia esquecido de ajustar a verificação da lista antes de desabilitar a caixa de combinação.

Assim, no exemplo o código deveria estar assim:

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
 // quando o cliente disconecta, ele é eliminado da lista
  ComboBox1.Items.Delete(ComboBox1.Items.IndexOfObject(Socket));
 // verifico maior que 1 porque o primeiro item da lista é "(Todos os Client's)". Então, 
 // apenas se houver 2 itens na lista é que teremos um client conectado
  AtualizaEstado(ComboBox1.Items.Count > 1);
end;

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Viva Micheus,

José, eu já corrigi o demo anexo ao tópico.

Era coisa simples. Ocorreu que inicialmente eu testava apenas usando Server e 1 Client, depois adaptei e não percebi que havia esquecido de ajustar a verificação da lista antes de desabilitar a caixa de combinação.

Ainda assim, não basta este código pra identificar qual o cliente que desligou. Apenas dá o endereço do IP e o que eu quero é quem/Cliente, se desconectou , por forma a limpar, quer na Memo2, quer no Lbox(n):

if (Pos('Cliente1', ClientId) = 1) and (Pos('exit',HexaValue)=1) then
Begin
  LBox1.Clear;     //Apaga os comandos dos clientes que desligam
end;
e,
Memo2.Lines.Delete(ClientIndex-1);
   Memo2.Lines.Insert(ClientIndex-1,ClientId+' Ausente')

Ainda assim, foi útil porque permitiu corrigir o facto de ao desligar um Cliente tornar inoperacional o campo...

Aquele abraço

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
      152k
    • Posts
      651,7k
×
×
  • Criar Novo...