-
А как же быть с тем меньшинством???? Для которых эта "абсолютно нормальная логика" не одходит. Я не говорю, что мой проэкт не подходит под поняти "подавляющее большинство распределённых приложений", но просто интересно как быть...??
-
Протокол инф.обмена должен соответствовать этой логике "меньшинства". Ну и, разумеется, реализация этого протокола должна быть соответствующей.
-
> PonosetcDM (17.06.2010 15:15:16) [16]
А ты сервер или спамер. Но ты имеешь право посылать сообщения подсоединившимся к тебе пользователям, если они готовы слушать тебя.
-
> PonosetcDM (17.06.2010 15:37:18) [18]
Постоянно опрашивать не надо, а надо ждать сообщения от сервера, как поступит так и обрабатывай. После установки соединения между сервером и клиентом нет разницы, они равноправны. Смотри методы и свойства TIdTCPServer и твоего клиента.
-
Anatoly Podgoretsky © (17.06.10 15:58) [23] Я не знаю прочитали вы полностью нашу с Сергеем переписку или нет, пэтому уточню суть проблеммы: Есть приложение с TIdTCPServer(сервер) и приложение с TIdTCPClient(клиент). 1. я делаю клиентом коннект к серверу IdTCPClient1.Connect; все хорошо, все подлючается, все работает. 2. я отправляю сообщение клиентом, серверу, он(сервер) обрабатывает его. все хорошо, все принято и обработано, все работает. 3. я посылаю сообщение сервером, клиенту, он(клиент) обрабатывает его. все хорошо, все принято и обработано, все работает.
Шаги 2 и 3 выполнять можно скока ХОШЬ....
4. делаю клиентом дисконнект. все дисконнектится все нормально... 5. делаю коннект, а вот тут "пффууук...." клиент грит, что он подконнектился, а сервер не реагирует, и ри попытке отправить сервером сообщение клиенту происходит "Connection Closed Grasfully"..., а при попытке повторного коннекта(без Disconnect), клиент говорит Already connected.. т.е. он считает, что он уже подключен...
-
> PonosetcDM (17.06.2010 16:24:24) [24]
Я как раз прочитал и ответил. После коннекта установлены двухсторонние отношения и клиент и сервер равноправны. Опрашивать ничего не надо, надо ждать сообщения в отдельном потоке конечно с использованием WaitForSingleObject
-
> PonosetcDM © (17.06.10 16:24) [24]
Ты так и не объяснил какая религия и почему запрещает тебе передавать данные клиенту непосредственнов в OnExecute
-
> PonosetcDM (17.06.2010 16:24:24) [24]
В ICS и это делать не надо, достаточно написать обработчик OnReceive, поток нужен для Инди. Но это моменты реализации.
-
Воооо.... ваще чума.... я запустил программу(сервер) подключился к ней по telnet из cmd, сервак послал клиенту сообщение, все окей, принято telnet'ом, обработано... закрываю telnet, открываю telnet, делаю коннект "типа все окей", сервак шлет сообщение клиенту и....... правильно "Connection Closed Grasfully"... ваще жуть...
-
> ваще чума
> ваще жуть
А скажи, любезный, вот ты заблокировал список Contexts, а разблокировать его за тебя кто будет, Пушкин ?
Ведь не ты один этим списком пользуешься - им еще и TIdCustomTCPServer пользуется, причем в 1-ю очередь !
При обработке событий коннекта/дисконнекта IdCustomTCPServer обращается к этому списку, выполняя попытку заблокировать его для внесения соотв.изменения, например, для удаления Item[0] после дисконнекта 1-го клиента и вновь создания Item[0] при коннекте ..
А ты взял и уселся на него верхом, не пуская никого покататься)
Вот тебе и грабли)
-
1. протокол - говно ты где видал что сначала идет список длинн, потом список данных (табличное представление не в счет) общепринято: длинна-значание, длинна-значение
2. описание структур - говно, дублирующие поля totalSize и ParamsLength в итоге потенциальное переполнение буфера когда totalSize<>Sum(ParamsLength)
3. работа с памятью - говно (cp := 2 + SizeOf(cardinal) + tmsg.fHeader.ParamCount * Sizeof(cardinal);)
4. работа с потоками - говно, общение с VCL в потоке (Memo1.Lines.Add)
это только про сервер... про клиента: таймер убил меня, читать дальше нет мочи
-
вот сравни с [3]procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
tmsg : TPackage;
i: byte;
recvfs: TFileStream;
MemoLines:string;
begin
with AContext.Connection.Socket,tmsg.fHeader,tmsg.fData do
begin
totalSize :=StrToInt64(ReadLn); cmd:=ReadByte;
ParamCount := ReadByte;
SetLength(ParamsLength,ParamCount);
for i:=0 to ParamCount-1 do
ParamsLength[i]:=ReadLongInt(false);
SetLength(Params,ParamCount);
for i:=0 to ParamCount-1 do
Params[i]:=ReadString(ParamsLength[i],enDefault);
MemoLines:='';
MemoLines:=MemoLines+'*********** We have a new message*******'+#13#10;
MemoLines:=MemoLines+' Message CMD Code = '+ IntToStr(tmsg.fHeader.cmd)+#13#10;
MemoLines:=MemoLines+' Message Params: '+#13#10;
for i:=0 to ParamCount-1 do
MemoLines:=MemoLines+' ' + (Params[i])+#13#10;
Case cmd of
1 : MemoLines:=MemoLines+'We have a new connection...'+#13#10;
2 : MemoLines:=MemoLines+'This is a message'+#13#10;
3 : begin
recvfs:= TFileStream.Create(ExtractFileName(Params[0])+'.tmp',fmCreate);
try
ReadStream(recvfs,StrToInt(Params[1]),false);
finally
recvfs.Free;
end;
MemoLines:=MemoLines+'-----> New File upload complete...'+#13#10;
end;
end;
end;
MemoLines:=MemoLines+'*********** End of new message*******'+#13#10;
end;
-
> делаю коннект "типа все окей", сервак шлет сообщение клиенту > и....... > правильно "Connection Closed Grasfully"... ваще жуть.. > .
Претензии к реализации сервера, невероятно кривая.
-
> Anatoly Podgoretsky © (18.06.10 10:31) [32]
Какая бы ни была кривая, но UnlockList-то надо вызывать)
-
procedure TForm1.SendPackage(pcmd, pparamCount: byte;
pparams: array of string);
var
tmsg:TPackage;
buf:TMemoryStream;
List:TList;
i:integer;
begin
buf:=TMemoryStream.Create;
try
with tmsg.fHeader,tmsg.fData do
begin
cmd:= pcmd;
ParamCount := pparamCount;
SetLength(ParamsLength,ParamCount);
SetLength(Params,ParamCount);
for i:=0 to ParamCount-1 do
begin
Params[i]:=pparams[i];
ParamsLength[i]:=length(Params[i]);
end;
buf.WriteBuffer(cmd,SizeOf(cmd));
buf.WriteBuffer(ParamCount,SizeOf(ParamCount));
for i:=0 to ParamCount-1 do
buf.WriteBuffer(ParamsLength[i],SizeOf(cardinal));
for i:=0 to ParamCount-1 do
buf.WriteBuffer(PChar(Params[i])^,ParamsLength[i]);
end;
List:=IdTCPServer1.Contexts.LockList;
try
for i:=0 to List.Count-1 do
with TIdContext(List.Items[i]).Connection.Socket do
begin
WriteLn(IntToStr(buf.Size));
Write(buf);
end;
finally
IdTCPServer1.Contexts.UnlockList; end;
finally
buf.Free; end;
end;
-
ЗАБЫЛ добавить: как только выходим из IdTCPServer1Execute - финиталякомедия конекшен рвется, так что переделывай в все в одном IdTCPServer1Execute или как то усыпляй IdTCPServer1Execute...
-
> Сергей М. (18.06.2010 10:34:33) [33]
Это часть кривизны.
-
Блин я согласен все замечания хороши, базара ноль... да вот проблемма остается актуальной.. на форме компоненты TIdTCPServer, TMemo и ТБатон вот код куда уж проще то...
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdBaseComponent, IdComponent, IdCustomTCPServer, IdTCPServer, IdContext, StdCtrls, Buttons;
type TForm1 = class(TForm) IdTCPServer1: TIdTCPServer; Memo1: TMemo; BitBtn1: TBitBtn; procedure IdTCPServer1Execute(AContext: TIdContext); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure BitBtn1Click(Sender: TObject); procedure IdTCPServer1Connect(AContext: TIdContext); procedure IdTCPServer1Disconnect(AContext: TIdContext); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext); var s:string; begin s:=AContext.Connection.IOHandler.ReadLn; Memo1.Lines.Add(s); end;
procedure TForm1.FormCreate(Sender: TObject); begin IdTCPServer1.Active:=true; end;
procedure TForm1.FormDestroy(Sender: TObject); begin IdTCPServer1.Active:=false; end;
procedure TForm1.BitBtn1Click(Sender: TObject); var i:integer; begin try for i:=0 to IdTCPServer1.Contexts.LockList.Count-1 do with TIdContext(IdTCPServer1.Contexts.LockList.Items[i]).Connection.Socket do WriteLn('123'); finally IdTCPServer1.Contexts.UnlockList; end; end;
procedure TForm1.IdTCPServer1Connect(AContext: TIdContext); begin Memo1.Lines.Add('we have a new connection') end;
procedure TForm1.IdTCPServer1Disconnect(AContext: TIdContext); begin Memo1.Lines.Add('Client disconnected'); end;
end.
иииииииии............ все теже грабли...
Запускаю эту прогу, запускаю телнет коннект телнета "o localhost 12312" нажимаю на батон, в окне телнета появляется "123", нажимаю на батон ищё раз, в окне телнета появляется ищё "123", закрываю телнет, срабатывает дисконнект запускаю телнет опять, прога при этом не перезапускалась(естественно)... делаю телнетом "o localhost 12312", и даже коннект у сервера не срабатывает.... все по шагам разжевал....
-
> все теже грабли
Ну где-же "теже" ? Connection closed gracefully как рукой сняло)
И, кстати, ты в [35] вник ?
-
Нууу не знаю что у Вас сняло, у мя как было так и осталось, какая у Вас версия Indy????
Про [35] хзхз, почиму это коннекшен рвется????
и что за усыпляй???
у мя когда клиент коннект сделал, заходит в и IdTCPServer1Execute(AContext: TIdContext); останавливается на AContext.Connection.IOHandler.ReadLn, пока не придет что-ть.
|