Текущий архив: 2008.04.27;
Скачать: CL | DM;
Вниз
Передать массив клиенту TIdTCPClient Найти похожие ветки
← →
vogel_max (2007-07-26 12:38) [0]Добрый день!
На форуме была эта тема, но понятного ответа или рабочего кода там нет.
Ничего не ругается просто не работает.
И ещё, как сделать чтобы сервер отправлял массив по требованию клиента без 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-26 12:42) [1]
> Client.ReadStream(t,t.Size,false);
Клиент у тебя говорит серверу - "дай 0 байт".
Ноль просил - ноль и получил)
← →
Сергей М. © (2007-07-26 13:02) [2]И к чему эти выкрутасы со стримами, если размер массива заранее известен и клиенту и серверу, тоже не понятно.
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;
← →
vogel_max (2007-07-26 14:05) [3]Вы правы ) . Спасибо. Просто уже клинит. А как сделать чтобы сервер отправлял данные по сообщению?
Вроде
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
*****
но что то виснет
← →
vogel_max (2007-07-26 14:07) [4]хм заменил
sCommand := AThread.Connection.ReadLn;
на
sCommand := AThread.Connection.ReadString(4);
заработало...
а как правильно? если команду любой длины захочется? )
← →
Сергей М. © (2007-07-26 14:15) [5]
> хм заменил
> sCommand := AThread.Connection.ReadLn;
> на
> sCommand := AThread.Connection.ReadString(4);
> заработало...
А это здесь причем ?
В приведенном тобой коде нет на стороне сервера никаких Read-вызовов, да и клиент твой в этом коде ничего не передает серверу.
> как правильно? если команду любой длины захочется
Что такое "команда" ?
Это содержимое того самого массива ?
А зачем для этого нужен массив ?
Поясни ..
← →
Сергей М. © (2007-07-26 14:17) [6]
> vogel_max (26.07.07 14:05) [3]
Да, теперь вижу.Client.WriteLn("send");
sCommand := AThread.Connection.ReadLn;
← →
vogel_max (2007-07-27 08:37) [7]Спасибо. Ещё вопрос. Сделал всё работает, но т.к. каждый раз 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-27 09:23) [8]
> Хочу сделать чтобы подключение было сделано один раз, а
> потом просто данные читать по таймеру
Просто перенеси код из обработчика кнопки 1 в обработчик таймера.
> клиент при повторной попытке Client.Write("send") уходит
> в finally
Это потому что сервер после выполнения обработчика OnExecute тут же разрывает соединение.
Необходимо поместить тело этого обработчика в while-цикл, завершающийся по условию PeerThread.Connection.Connected = False
← →
vogel_max (2007-07-27 11:11) [9]сделал цикл, но тоже самое получается - клиент первый раз читает, на второй 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 12:03) [10]
> на второй connection closed gracefully
А что говорит отладчик при трассировке ServerExecute ?
← →
vogel_max (2007-07-27 12:56) [11]ругается при выполнении t.free во второй раз
......
t.Free;
finally
t.Free;
........
убрал первый вызов free - клиент данные не получает ошибка - read timeout
убрал второй - тоже самое
← →
Сергей М. © (2007-07-27 13:00) [12]И долго ты экспериментировать вслепую будешь ?
Брейкпойнт на until-операторе ловишь или не ловишь ?
← →
SlymRO © (2007-07-27 13:06) [13]Двойной 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 14:08) [14]
> Двойной Free объекту
Он оба Free убрал , см. [11]
При этом у него другие чудеса начались)
Страницы: 1 вся ветка
Текущий архив: 2008.04.27;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.017 c