![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Передать массив клиенту TIdTCPClient [D7, WinXP]
vogel_max © (2007-07-26 12:38:00)Добрый день!
На форуме была эта тема, но понятного ответа или рабочего кода там нет.
Ничего не ругается просто не работает.
И ещё, как сделать чтобы сервер отправлял массив по требованию клиента без Disconnect постоянного. Т.к. отправлять надо будет постоянно, часто и очень много )
есть сервер, он должен отдавать клиентам массив данных:
procedure TForm1.ServerExecute(AThread: TIdPeerThread);
const ar : array[0..5] of char = ('A','B','C',#39,#00,'B');
var t:TMemoryStream;
begin
try
t := TMemoryStream.Create;
t.Write(ar[0],sizeof(ar));
t.Position := 0;
Athread.Connection.WriteStream(t,false,false);
AThread.Connection.Disconnect;
finally
t.Free;
end;
end;
и клиент который сохраняет массив:
procedure TForm1.Button1Click(Sender: TObject);
var
t : TMemoryStream;
ar : array [0..5] of char;
begin
try
t := TMemoryStream.Create;
t.Position := 0;
Client.Connect;
Client.ReadStream(t,t.Size,false);
Client.Disconnect;
t.Position:=0;
t.Read(ar,t.Size);
finally
t.Free;
end;
end;
Сергей М. (2007-07-27 14:08:00) [1]
> Двойной Free объекту
Он оба Free убрал , см. [11]
При этом у него другие чудеса начались)
SlymRO (2007-07-27 13:06:00) [2]Двойной Free объекту!
procedure TForm1.ServerExecute(AThread: TIdPeerThread);
var
t:TMemoryStream;
sCommand: string;
begin
repeat
begin
sCommand := AThread.Connection.ReadString(4);
if SameText(sCommand, 'send') then
begin
t := TMemoryStream.Create;
try
t.Write(data,sizeof(data));
t.Position := 0;
Athread.Connection.WriteStream(t,false,false);
finally
t.Free;
end;
end;
end
until(AThread.Connection.Connected=false);
end;
Сергей М. (2007-07-27 13:00:00) [3]И долго ты экспериментировать вслепую будешь ?
Брейкпойнт на until-операторе ловишь или не ловишь ?
vogel_max (2007-07-27 12:56:00) [4]ругается при выполнении t.free во второй раз
......
t.Free;
finally
t.Free;
........
убрал первый вызов free - клиент данные не получает ошибка - read timeout
убрал второй - тоже самое
Сергей М. (2007-07-27 12:03:00) [5]
> на второй connection closed gracefully
А что говорит отладчик при трассировке ServerExecute ?
vogel_max (2007-07-27 11:11:00) [6]сделал цикл, но тоже самое получается - клиент первый раз читает, на второй connection closed gracefully
procedure TForm1.ServerExecute(AThread: TIdPeerThread);
var
t:TMemoryStream;
sCommand: string;
begin
repeat
begin
sCommand := AThread.Connection.ReadString(4);
if SameText(sCommand, 'send') then
begin
try
t := TMemoryStream.Create;
t.Write(data,sizeof(data));
t.Position := 0;
Athread.Connection.WriteStream(t,false,false);
t.Free;
finally
t.Free;
end;
end;
end
until(AThread.Connection.Connected=false);
end;
Сергей М. (2007-07-27 09:23:00) [7]
> Хочу сделать чтобы подключение было сделано один раз, а
> потом просто данные читать по таймеру
Просто перенеси код из обработчика кнопки 1 в обработчик таймера.
> клиент при повторной попытке Client.Write('send') уходит
> в finally
Это потому что сервер после выполнения обработчика OnExecute тут же разрывает соединение.
Необходимо поместить тело этого обработчика в while-цикл, завершающийся по условию PeerThread.Connection.Connected = False
vogel_max (2007-07-27 08:37:00) [8]Спасибо. Ещё вопрос. Сделал всё работает, но т.к. каждый раз connect а данные (2000 элементов массив) я читаю каждые пол секунды, то порт удалённый постоянно увеличивается. Сервер сваливается где то за полминуты, думаю из за этого.
Хочу сделать чтобы подключение было сделано один раз, а потом просто данные читать по таймеру. Вот что получилось (клиент при повторной попыткеClient.Write('send')уходит в finally):
клиент (сейчас перечитывает по нажатии button1, потом будет по таймеру):
procedure TForm1.Button4Click(Sender: TObject);
begin
Client.Connect; // client: TIdTCPClient;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
t : TMemoryStream;
i: integer;
begin
try
t := TMemoryStream.Create;
t.Position := 0;
client.;
Client.Write('send');
Client.ReadStream(t,SizeOf(data),true);
t.Position:=0;
t.Read(data,t.Size);
finally
t.Free;
end;
end;
сервер:
procedure TForm1.ServerExecute(AThread: TIdPeerThread);
var
t:TMemoryStream;
sCommand: string;
begin
sCommand := AThread.Connection.ReadString(4);
if SameText(sCommand, 'send') then
begin
Edit1.Text:= sCommand;
try
t := TMemoryStream.Create;
t.Write(data,sizeof(data));
t.Position := 0;
Athread.Connection.WriteStream(t,false,false);
t.Free;
finally
t.Free;
end;
end;
end;
Сергей М. (2007-07-26 14:17:00) [9]
> vogel_max (26.07.07 14:05) [3]
Да, теперь вижу.
Client.Write Ln('send');
sCommand := AThread.Connection.Read Ln;
Сергей М. (2007-07-26 14:15:00) [10]
> хм заменил
> sCommand := AThread.Connection.ReadLn;
> на
> sCommand := AThread.Connection.ReadString(4);
> заработало...
А это здесь причем ?
В приведенном тобой коде нет на стороне сервера никаких Read-вызовов, да и клиент твой в этом коде ничего не передает серверу.
> как правильно? если команду любой длины захочется
Что такое "команда" ?
Это содержимое того самого массива ?
А зачем для этого нужен массив ?
Поясни ..
vogel_max (2007-07-26 14:07:00) [11]хм заменил
sCommand := AThread.Connection.ReadLn;
на
sCommand := AThread.Connection.ReadString(4);
заработало...
а как правильно? если команду любой длины захочется? )
vogel_max (2007-07-26 14:05:00) [12]Вы правы ) . Спасибо. Просто уже клинит. А как сделать чтобы сервер отправлял данные по сообщению?
Вроде
procedure TForm1.Button1Click(Sender: TObject);
var
t : TMemoryStream;
ar : array [0..5] of char;
begin
try
t := TMemoryStream.Create;
t.Position := 0;
Client.Connect;
Client.Write('send'); // говорю серверу что жду
Client.ReadStream(t,SizeOf(ar),true);
а серверу добавил:
procedure TForm1.ServerExecute(AThread: TIdPeerThread);
****
sCommand := AThread.Connection.ReadLn;
if SameText(sCommand, 'send') then
begin
*****
но что то виснет
Сергей М. (2007-07-26 13:02:00) [13]И к чему эти выкрутасы со стримами, если размер массива заранееизвестен и клиенту и серверу, тоже не понятно.
procedure TForm1.ServerExecute(AThread: TIdPeerThread);
const
ar: array[0..5] of char = ('A','B','C',#39,#00,'B');
begin
..
Athread.Connection.WriteBuffer(ar, SizeOf(ar), True);
..
end;
procedure TForm1.Button1Click(Sender: TObject);
var
ar : array [0..5] of char;
begin
..
Client.ReadBuffer(ar, SizeOf(ar));
..
end;
Сергей М. (2007-07-26 12:42:00) [14]
> Client.ReadStream(t,t.Size,false);
Клиент у тебя говорит серверу - "дай 0 байт".
Ноль просил - ноль и получил)