AThread
Eu estou usando os componentes idTCPServer e idTCPCliente.
Para armazenar os AThread dos clientes e algumas informacoes sobre ele fiz o seguinte:
Dentro de PPc eu coloco as informações e o AThread quando conecta, e guardo no TList
O problema é que quando ele conecta da um erro doido e ele da erro na hora de colocar o AThread, já fiz de tudo mas nada resolve o problema.
E fiz praticamente igual ao do exemplo do Indy e mesmo assim não funciona.
Alguem pode me ajudar??
Para armazenar os AThread dos clientes e algumas informacoes sobre ele fiz o seguinte:
PPc = ^TPc; TPc = Record Thread: TIdPeerThread; Ip: String; Cliente: String; ClienteN: Integer; Pc: Integer;
Dentro de PPc eu coloco as informações e o AThread quando conecta, e guardo no TList
O problema é que quando ele conecta da um erro doido e ele da erro na hora de colocar o AThread, já fiz de tudo mas nada resolve o problema.
E fiz praticamente igual ao do exemplo do Indy e mesmo assim não funciona.
Alguem pode me ajudar??
Rudá
Curtidas 0
Respostas
Massuda
11/01/2006
Talvez você devesse dar uma olhada no exemplo IdTCPDemo. Note que os dados dos clientes são guardados numa TThreadList, que é uma lista thread safe; um TList não serve porque podem ocorrer problemas de sincronismo durante a execução.
É importante lembrar que a thread/conexão do cliente pode a qualquer instante deixar de existir.
Existem outras formas de manter a lista dos clientes conectados, mas isso depende do que você pretende fazer.
É importante lembrar que a thread/conexão do cliente pode a qualquer instante deixar de existir.
Existem outras formas de manter a lista dos clientes conectados, mas isso depende do que você pretende fazer.
GOSTEI 0
Rudá
11/01/2006
E aonde baixo esse Demo??
GOSTEI 0
Massuda
11/01/2006
[url=http://www.indyproject.org/Sockets/Demos/index.en.html]Nesta página[/url] do site oficial do Indy.
GOSTEI 0
Rudá
11/01/2006
Achei e testei, tudo blz o problema é quando fui dar um count, ele para de funcionar quando fecho o o cliente ele nao desconecta, e da tudo errado.
O que pode ser??
O que pode ser??
GOSTEI 0
Massuda
11/01/2006
O que pode ser??
Você precisaria dar mais detalhes para ser possível dizer alguma coisa... note que não basta apenas o código, mas sim o que você está tentando fazer.GOSTEI 0
Rudá
11/01/2006
Tentei resolver, mas não consegui, agora to tentando usar array, mas da erro: [b:35ec1c308b]No execute handler found[/b:35ec1c308b]
Decclarei: [b:35ec1c308b]Thread: Array of TIdPeerThread;[/b:35ec1c308b]
E na função: [b:35ec1c308b]TCPServerConnect[/b:35ec1c308b] coloquei: [b:35ec1c308b]SetLength(Thread,1); Thread[0]:= AThread;[/b:35ec1c308b]
E na função: [b:35ec1c308b]TCPServerDisconnect[/b:35ec1c308b] coloquei: [b:35ec1c308b]Thread[0]:= nil;[/b:35ec1c308b]
Quando conecto ele da o erro.
O que pode ser???
Decclarei: [b:35ec1c308b]Thread: Array of TIdPeerThread;[/b:35ec1c308b]
E na função: [b:35ec1c308b]TCPServerConnect[/b:35ec1c308b] coloquei: [b:35ec1c308b]SetLength(Thread,1); Thread[0]:= AThread;[/b:35ec1c308b]
E na função: [b:35ec1c308b]TCPServerDisconnect[/b:35ec1c308b] coloquei: [b:35ec1c308b]Thread[0]:= nil;[/b:35ec1c308b]
Quando conecto ele da o erro.
O que pode ser???
GOSTEI 0
Massuda
11/01/2006
No execute handler found
Esse ocorre porque você precisa ter pelo menos um item na lista CommandHandlers (ou estar com CommandJHandlersEnabled = False).Decclarei: [b:b30ec0bd03]Thread: Array of TIdPeerThread;[/b:b30ec0bd03]....
Um servidor Indy trata cada cliente usando uma thread, ou seja, o servidor é multithread.Por causa disso, qualquer código que envolva mais de um cliente (que é o caso do que você está tentando fazer) precisa ser thread-safe, ou seja, precisa ter algum mecanismo que permita compartilhamento de dados (caso do TThreadList) e/ou (se for o caso) que garanta sincronismo entre diferentes threads. O exemplo do Indy que citei num post anterior usa um TThreadList.
Pelo que você postou, o código pode eventualmente até funcionar para um único cliente, mas falhará (de modo aleatório) quando mais de um cliente se conectar ao servidor. Estude mais o exemplo que citei e implemente algo parecido.
Outra coisa... seja lá o que você pretenda fazer, não utilize a thread do cliente que você está armazenando na estrutura de dados sem antes bloquear o servidor. Normalmente, você faz isso assim...
var List: TList; Peer: TIdPeerThread; ... List := IdTCPServer1.Threads.LockList; //isso bloqueia o servidor! try for I := 0 to List.Count - 1 do begin // List[I] é uma das threads do servidor Peer := TIdPeerThread(List[I]); Peer.Connection.WriteLn(´Oi´); end; finally IdTCPServer1.Threads.UnlockList end;
Uma alternativa é você derivar uma classe de TIdPeerThread e incluir nessa classe derivada os dados que você desejar; preencha esses dados no OnConnect do servidor. Você diz ao servidor para usar sua classe ao invés de TIdPeerThread através da propriedade TIdTCPServer.ThreadClass.
GOSTEI 0
Rudá
11/01/2006
OK,
Pode me ajudar, qual é a melhor opção?
Pode me ajudar, qual é a melhor opção?
GOSTEI 0
Rudá
11/01/2006
Fiz esse exemplo simples e não funciona.
Server:
Cliente:
E não funciona da um erro doido quando o cliente conecta:
Project server.exe raised exception class EAccessViolation with message ´Access violation at address 00413AEF in module ´server.exe´. Read of address ´00000008´. Process stopped. Use Step or Run to continue.
Nem sei o que pode ser, o exemplo é simples e deveria funcionar e nada de funcionar.
Server:
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdThreadMgr, IdThreadMgrDefault, IdBaseComponent,
IdComponent, IdTCPServer;
type
TForm1 = class(TForm)
TCPServer: TIdTCPServer;
Memo: TMemo;
Button1: TButton;
ThreadMgr: TIdThreadMgrDefault;
procedure TCPServerConnect(AThread: TIdPeerThread);
procedure FormShow(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure TCPServerDisconnect(AThread: TIdPeerThread);
private
{ Private declarations }
public
Thread: TList;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormShow(Sender: TObject);
begin
TCPServer.Active:= True;
end;
procedure TForm1.TCPServerConnect(AThread: TIdPeerThread);
begin
Thread.Add(AThread);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
Memo.Lines.Clear;
for i:= 0 to Thread.Count-1 do
Memo.Lines.Add(TIdPeerThread(Thread[i]).Connection.Socket.Binding.PeerIP);
end;
procedure TForm1.TCPServerDisconnect(AThread: TIdPeerThread);
begin
Thread.Remove(AThread);
end;
end.Cliente:
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
IdTCPClient, IdAntiFreezeBase, IdAntiFreeze;
type
TForm_Principal = class(TForm)
TCPClient: TIdTCPClient;
IP: TEdit;
Button1: TButton;
AntiFreeze: TIdAntiFreeze;
Memo: TMemo;
procedure Button1Click(Sender: TObject);
procedure TCPClientConnected(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TClientThread = class(TThread)
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean);
end;
var
Form_Principal: TForm_Principal;
implementation
{$R *.dfm}
procedure TForm_Principal.Button1Click(Sender: TObject);
begin
TCPClient.Host:= IP.Text;
TCPClient.Connect;
end;
constructor TClientThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
Priority := tpIdle;
FreeOnTerminate:= true;
end;
procedure TClientThread.Execute;
begin
inherited;
with Form_Principal do
begin
if not TCPClient.Connected then
exit;
repeat
Form_Principal.Memo.Lines.Add(TCPClient.ReadLn);
until not TCPClient.Connected;
end;
end;
procedure TForm_Principal.TCPClientConnected(Sender: TObject);
begin
TClientThread.Create(false);
end;
end.E não funciona da um erro doido quando o cliente conecta:
Project server.exe raised exception class EAccessViolation with message ´Access violation at address 00413AEF in module ´server.exe´. Read of address ´00000008´. Process stopped. Use Step or Run to continue.
Nem sei o que pode ser, o exemplo é simples e deveria funcionar e nada de funcionar.
GOSTEI 0
Massuda
11/01/2006
Sem querer ofender, numa rápida olhada, eu diria que seu código pode até funcionar, mas está errado.
Antes de prosseguir, o que você está tentando implementar?
Antes de prosseguir, o que você está tentando implementar?
GOSTEI 0
Rudá
11/01/2006
Eu estou tentando fazer tipo um sistema de lan house.
GOSTEI 0