enviar um vetor, trabalhando com sockets
Olá pessoal, preciso de ajuda ok.
vamos ver se vocês conseguem me ajudar, o meu problema é o seguinte, tenho uma aplicação onde fica constantemente lendo alguns dados de um CLP(controlador logico progrmavel) estes dados me são retornados dentro de um vetor ok, ate ai perfeito o problema é o seguinte, quando um cliente se conectar a o meu servidor e mandar uma requisição de leitura, eu tenho que mandar esse vetor pra ele, ai é que esta o problema como mandar um vetor, ou se alguem tiver alguma outra ideia do que poderia fazer fico grato.
estou utilizando os componentes TClientSocket e TServerSocket, mandar um valor eu conigo,mas o vetor inteiro não..
bom aguardo dicas de vc´s ok
abraços.
vamos ver se vocês conseguem me ajudar, o meu problema é o seguinte, tenho uma aplicação onde fica constantemente lendo alguns dados de um CLP(controlador logico progrmavel) estes dados me são retornados dentro de um vetor ok, ate ai perfeito o problema é o seguinte, quando um cliente se conectar a o meu servidor e mandar uma requisição de leitura, eu tenho que mandar esse vetor pra ele, ai é que esta o problema como mandar um vetor, ou se alguem tiver alguma outra ideia do que poderia fazer fico grato.
estou utilizando os componentes TClientSocket e TServerSocket, mandar um valor eu conigo,mas o vetor inteiro não..
bom aguardo dicas de vc´s ok
abraços.
Perdiga
Curtidas 0
Respostas
Perdiga
18/05/2006
e ai galera, ninguem tem alguma ideia.
GOSTEI 0
Kroki
18/05/2006
Não entendí oque vc quer dizer com ´vetor´...
GOSTEI 0
Perdiga
18/05/2006
seguinte amigo vou tentar ser mais claro ok..
eu trabalho com Automação industrial e utilizo delphi para fazer meus supervisorios, ou seja tenho uma aplicação que fica lendo dento de um timer dados de um clp e esses dados são atribuidos a um vetor neste caso é um vetor de 30 posições ok... o que tenho que fazer é simples é passar esses dados que estão no vetor para o meu client para que ele mostre os dados na tela entendeu...
o que eu estou fazendo agora e me parece que não deu certo foi o seguinte quando meu cliente manda uma pergunta para o server que é o aplicativo onde esta fazendo esta leitura... no evento onRead do server eu fiz o seuinte
for i:=0 to 30 do
server.socket.conections[0].sendText(vetor[i]);
é isso que estou fazeno e no outro lado estou tentando remontar esse vetor.... mas o que percebi é que quando vai para o outro lado ele envia todos os dados de uma vez, so que com isso não consigo saber quais os dados nas suas posições..
não sei se você conseguiu me entender qualquer coisa é so falar.....
eu trabalho com Automação industrial e utilizo delphi para fazer meus supervisorios, ou seja tenho uma aplicação que fica lendo dento de um timer dados de um clp e esses dados são atribuidos a um vetor neste caso é um vetor de 30 posições ok... o que tenho que fazer é simples é passar esses dados que estão no vetor para o meu client para que ele mostre os dados na tela entendeu...
o que eu estou fazendo agora e me parece que não deu certo foi o seguinte quando meu cliente manda uma pergunta para o server que é o aplicativo onde esta fazendo esta leitura... no evento onRead do server eu fiz o seuinte
for i:=0 to 30 do
server.socket.conections[0].sendText(vetor[i]);
é isso que estou fazeno e no outro lado estou tentando remontar esse vetor.... mas o que percebi é que quando vai para o outro lado ele envia todos os dados de uma vez, so que com isso não consigo saber quais os dados nas suas posições..
não sei se você conseguiu me entender qualquer coisa é so falar.....
GOSTEI 0
Kroki
18/05/2006
Não sei se isso te da uma luz porque uso Indy,mas tenho um aplicativo que le informações de tamanho variavel de um terminal.
...
IdTCPClient1.WriteLn(´unid´);//comando
while s <> ´fim´do begin
s:=IdTCPClient1.ReadLn;
ListBox1.Items.Append(s);
end;
IdTCPClient1.Disconnect;
Quando achado a string ´fim´ os dados estão todos no ListBox.
O programa Servidor envia o conteudo do memo;
...
for i:=0 to Memo1.Lines.Count-1 do begin
ASender.Thread.Connection.writeln(Memo1.Lines.Strings[i]);
end;
ASender.Thread.Connection.writeln(´fim´);
end;
...
...
IdTCPClient1.WriteLn(´unid´);//comando
while s <> ´fim´do begin
s:=IdTCPClient1.ReadLn;
ListBox1.Items.Append(s);
end;
IdTCPClient1.Disconnect;
Quando achado a string ´fim´ os dados estão todos no ListBox.
O programa Servidor envia o conteudo do memo;
...
for i:=0 to Memo1.Lines.Count-1 do begin
ASender.Thread.Connection.writeln(Memo1.Lines.Strings[i]);
end;
ASender.Thread.Connection.writeln(´fim´);
end;
...
GOSTEI 0
Thomaz_prg
18/05/2006
Bom, agora não tenho como testar, mas vejo algumas formas de se fazer isso:
1. Criar um string que tenha todos os valores, onde os valores são delimitados. Por exemplo:
str := v1+´;´+v2+´;´+v3+´;´;
e daí para enviar:
server.socket.conections[0].sendText(str);
daí no cliente você só trataria a separação dos ítems.
2. Enviar uma variável do tipo Variant pelo SenBuf, onde essa variável seria o vetor. Tipo:
vvariant := VarArrayOf( [v1, v2, v3 ] );
para enviar:
server.socket.connections[0].sendbuf(vvariant);
no cliente, seria só passar o que foi recebido por ReceiveBuf para uma variável do tipo variant, e acessar diretamente os ítens:
vvariant[0], vvariant[1], etc....
Essas, creio eu, serem as mais simples de implementar.
1. Criar um string que tenha todos os valores, onde os valores são delimitados. Por exemplo:
str := v1+´;´+v2+´;´+v3+´;´;
e daí para enviar:
server.socket.conections[0].sendText(str);
daí no cliente você só trataria a separação dos ítems.
2. Enviar uma variável do tipo Variant pelo SenBuf, onde essa variável seria o vetor. Tipo:
vvariant := VarArrayOf( [v1, v2, v3 ] );
para enviar:
server.socket.connections[0].sendbuf(vvariant);
no cliente, seria só passar o que foi recebido por ReceiveBuf para uma variável do tipo variant, e acessar diretamente os ítens:
vvariant[0], vvariant[1], etc....
Essas, creio eu, serem as mais simples de implementar.
GOSTEI 0
Perdiga
18/05/2006
poxa valeu amigos por essas dicas de vc´s, eu não tenho como testar elas aqui agora so segunda-feira, mas assim que testar posto se deu certo ou não ok.. muito obrigado mesmo galera.
Abraços.
Abraços.
GOSTEI 0
Perdiga
18/05/2006
ola Kroki.
Bom tentei do seu jeito, mas não da certo ele trava e não vai em frente.
olha o que fiz...
servidor.
for i:=0 to 30 do
MeuServidor.Socket.Connections[0].SendText(IntToStr(blcGeral[i]));
MeuServidor.Socket.Connections[0].SendText(´fim´);
e no cliente
i:=0;
msg:=Socket.ReceiveText;
while msg <> ´fim´ do
begin
ListBox1.Items.Append(msg);
inc(i);
end;
bom quando executo isso amigo, trava tudo........
quanto ao amigo thomaz_prg
acho que a primeira alternativa não seria a melhor entende... por ser um vetor de 30 posições que tenho, mas isso pode variar posso ter mais, então creio que não seje a melhor maneira, pelo motivo de ter que ficar passando posição a posição, em questão de 2 alternativa não entendi muito bem não se vc pudesse explicar com um pouco a mais de detalhes ficaria grato....
valeu..
Bom tentei do seu jeito, mas não da certo ele trava e não vai em frente.
olha o que fiz...
servidor.
for i:=0 to 30 do
MeuServidor.Socket.Connections[0].SendText(IntToStr(blcGeral[i]));
MeuServidor.Socket.Connections[0].SendText(´fim´);
e no cliente
i:=0;
msg:=Socket.ReceiveText;
while msg <> ´fim´ do
begin
ListBox1.Items.Append(msg);
inc(i);
end;
bom quando executo isso amigo, trava tudo........
quanto ao amigo thomaz_prg
acho que a primeira alternativa não seria a melhor entende... por ser um vetor de 30 posições que tenho, mas isso pode variar posso ter mais, então creio que não seje a melhor maneira, pelo motivo de ter que ficar passando posição a posição, em questão de 2 alternativa não entendi muito bem não se vc pudesse explicar com um pouco a mais de detalhes ficaria grato....
valeu..
GOSTEI 0
Perdiga
18/05/2006
galera olha so o que esta acontecendo, mudei um pouco as coisas..
no servidor criei um vetor para teste de 5 posições
no onRead tenho isso.
var
msg : string;
NumConex : integer;
begin
NumConex := Conexoes.IndexOf(Socket.Data);
if NumConex >= 0 then
msg := socket.ReceiveText; // pego a menssagem q chegou
if msg = ´R1´ Then
Leitura(NumConex);
o procedimento leitura faz isso..
var
i : integer;
begin
for i:=1 to 5 do
MeuServidor.Socket.Connections[NCon].SendText(IntToStr(vetor[i]));
end;
no cliente estou recebendo deste jeito.
begin
msg:=Socket.ReceiveText;
ListBox1.Items.add(msg);
end;
o que acontece é o seguinte tenho um botão enviar que tem o seguinte codigo
ListBox1.Clear;
If ClientSocket1.Active then
ClientSocket1.Socket.SendText(´R1´)
else
ShowMessage(´Voce não esta conectado com o servidor´);
end;
que envia uma requisição.
o que acontece é o seguinte na hora que mando enviar as vezes ele me devolve no meu listbox assim
ve vetor tenho os seguintes dados.
vetor[1]:= 2;
vetor[2]:= 50;
vetor[3]:= 3;
vetor[4]:= 5;
vetor[5]:= 6;
ai no Listbox as vezes vem correto que seria assim que deveria sempre aparecer
2
50
3
5
6
as vezes vem assim
250356
ou
2
50
356
e assim por diante ele não aparece sempre do mesmo jeito..
galera to apavorado preciso disso e não estou conseguindo
alguem tem alguma forma de se fazer isso..
valeu
no servidor criei um vetor para teste de 5 posições
no onRead tenho isso.
var
msg : string;
NumConex : integer;
begin
NumConex := Conexoes.IndexOf(Socket.Data);
if NumConex >= 0 then
msg := socket.ReceiveText; // pego a menssagem q chegou
if msg = ´R1´ Then
Leitura(NumConex);
o procedimento leitura faz isso..
var
i : integer;
begin
for i:=1 to 5 do
MeuServidor.Socket.Connections[NCon].SendText(IntToStr(vetor[i]));
end;
no cliente estou recebendo deste jeito.
begin
msg:=Socket.ReceiveText;
ListBox1.Items.add(msg);
end;
o que acontece é o seguinte tenho um botão enviar que tem o seguinte codigo
ListBox1.Clear;
If ClientSocket1.Active then
ClientSocket1.Socket.SendText(´R1´)
else
ShowMessage(´Voce não esta conectado com o servidor´);
end;
que envia uma requisição.
o que acontece é o seguinte na hora que mando enviar as vezes ele me devolve no meu listbox assim
ve vetor tenho os seguintes dados.
vetor[1]:= 2;
vetor[2]:= 50;
vetor[3]:= 3;
vetor[4]:= 5;
vetor[5]:= 6;
ai no Listbox as vezes vem correto que seria assim que deveria sempre aparecer
2
50
3
5
6
as vezes vem assim
250356
ou
2
50
356
e assim por diante ele não aparece sempre do mesmo jeito..
galera to apavorado preciso disso e não estou conseguindo
alguem tem alguma forma de se fazer isso..
valeu
GOSTEI 0
Thomaz_prg
18/05/2006
Após a linha que tem o comando
MeuServidor.Socket.Connections[NCon].SendText(IntToStr(vetor[i]));
coloque uma espera:
Sleep(300);
MeuServidor.Socket.Connections[NCon].SendText(IntToStr(vetor[i]));
coloque uma espera:
Sleep(300);
GOSTEI 0
Perdiga
18/05/2006
não adianta não amigo..
infelizmente não funcionou..
mais alguma dica não faço a minima ideia do pq esteja acontecendo isso
teoricamente não deveria..
vou lhe falar uma coisa
quando coloquei um breakpoint no for que envia para o client
for i:=1 to 5 do
MeuServidor.Socket.Connections[NCon].SendText(IntToStr(vetor[i]));
ao invez de fazer na primeira passada i = 1, i = 2 e assim por diante, ele esta fazendo em ordem decrescente na primeira passada ele faz o seguinte
i = 5,i=4 e assim por diante, não sei se tem alguma coisa a ver mas so para comentar
abraço.
infelizmente não funcionou..
mais alguma dica não faço a minima ideia do pq esteja acontecendo isso
teoricamente não deveria..
vou lhe falar uma coisa
quando coloquei um breakpoint no for que envia para o client
for i:=1 to 5 do
MeuServidor.Socket.Connections[NCon].SendText(IntToStr(vetor[i]));
ao invez de fazer na primeira passada i = 1, i = 2 e assim por diante, ele esta fazendo em ordem decrescente na primeira passada ele faz o seguinte
i = 5,i=4 e assim por diante, não sei se tem alguma coisa a ver mas so para comentar
abraço.
GOSTEI 0
Thomaz_prg
18/05/2006
O seu código ficou assim???
Se não funcionou assim, tente fazer da forma com a qual eu havia dito...
Da primeira forma, eu achei viável, pois ficaria assim (envio):
Para receber:
Dessa forma, independente do tamanho do vetor, você poderia enviar ou receber os dados do vetor normalmente. Daria também para setar o tamanho do vetor em tempo de execução usando SetLength, e enviando, na primeira posição, o tamanho do vetor.
for i:=1 to 5 do begin MeuServidor.Socket.Connections[NCon].SendText(IntToStr(vetor[i])); sleep(300); end;
Se não funcionou assim, tente fazer da forma com a qual eu havia dito...
Da primeira forma, eu achei viável, pois ficaria assim (envio):
var valor:string; i:integer; begin valor := ´´; for i := 1 to 30 do //Percorrer o vetor valor := valor + vetor[i] + ´;´ ; MeuServidor.Socket.Connections[NCon].SendText( valor ); end
Para receber:
var valor, v :string; i:integer; begin valor := Socket.ReceiveText; i := 0 ; //posição inicial do vetor; while pos(´;´ , valor ) > 0 do begin v := copy( valor , 1 , pos(´;´,valor)-1 ); valor := copy( valor , pos(´;´,valor)+1 , length(valor) ); vetor[i] := v; i := i + 1; end; end;
Dessa forma, independente do tamanho do vetor, você poderia enviar ou receber os dados do vetor normalmente. Daria também para setar o tamanho do vetor em tempo de execução usando SetLength, e enviando, na primeira posição, o tamanho do vetor.
GOSTEI 0
Perdiga
18/05/2006
O seu código ficou assim???
desculpa amigo, não tinha colocado o sleep dentro do begin não, agora eu testei e a principio funcionou.
Se não funcionou assim, tente fazer da forma com a qual eu havia dito...
Da primeira forma, eu achei viável, pois ficaria assim (envio):
Para receber:
Dessa forma, independente do tamanho do vetor, você poderia enviar ou receber os dados do vetor normalmente. Daria também para setar o tamanho do vetor em tempo de execução usando SetLength, e enviando, na primeira posição, o tamanho do vetor.
for i:=1 to 5 do begin MeuServidor.Socket.Connections[NCon].SendText(IntToStr(vetor[i])); sleep(300); end;
var valor:string; i:integer; begin valor := ´´; for i := 1 to 30 do //Percorrer o vetor valor := valor + vetor[i] + ´;´ ; MeuServidor.Socket.Connections[NCon].SendText( valor ); end
var valor, v :string; i:integer; begin valor := Socket.ReceiveText; i := 0 ; //posição inicial do vetor; while pos(´;´ , valor ) > 0 do begin v := copy( valor , 1 , pos(´;´,valor)-1 ); valor := copy( valor , pos(´;´,valor)+1 , length(valor) ); vetor[i] := v; i := i + 1; end; end;
bom, mas vou testar essa outra forma sua sim.... , já lhe digo se funcionou esta forma ok..
abração amigo e valeu por vc estar me ajudando.
GOSTEI 0
Perdiga
18/05/2006
blz amigão, parece que esse seu código, esta funcionando que é uma maravilha, nos testes, agora vamos ter que colocar ele funcionando para ver se vai continuar legal..... ficou bem melho que colocar um sleep. é pq eu vou fazer uma leitura a cada 1s e mais de um cliente pode estar fazendo entende, por isso necessito de melhor performace..
mas acredito que com esse seu codigo va funcionar legal, não tinha pensado nisso ainda amigo, quando voçê deu a sujestão imaginava outra coisa... principiante no mundo da programação é isso mesmo né amigo, mas um dia chego lá ainda mais com ajuda que estou tendo do pessoal..
valeu mesmo e abraço eim, qualquer coisa vou voltar a postar aqui para dizer se funcionou legal..
fiz os testes enviando um vetor de apenas 5 posições, vamos ver depois ok..
mais uma vez obrigado.
mas acredito que com esse seu codigo va funcionar legal, não tinha pensado nisso ainda amigo, quando voçê deu a sujestão imaginava outra coisa... principiante no mundo da programação é isso mesmo né amigo, mas um dia chego lá ainda mais com ajuda que estou tendo do pessoal..
valeu mesmo e abraço eim, qualquer coisa vou voltar a postar aqui para dizer se funcionou legal..
fiz os testes enviando um vetor de apenas 5 posições, vamos ver depois ok..
mais uma vez obrigado.
GOSTEI 0