Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Система";
Текущий архив: 2004.01.16;
Скачать: [xml.tar.bz2];

Вниз

---|Ветка была без названия|---   Найти похожие ветки 

 
h0use   (2003-10-30 16:57) [40]

Короче, стартует вроде один раз, создаю все объекты при старте как create(self), но все арвно клиент не может ничего отправить на сервер


 
Digitman   (2003-10-30 17:09) [41]


> h0use



> Короче, стартует вроде один раз


значит, лажовый твой "логгер"


> но все арвно клиент не может ничего отправить на сервер


а это уже все ближе и ближе ведет к неправильной логике работы непосредственно с серверным объектом

сервис, как видишь, ни при чем.


 
h0use   (2003-10-30 17:17) [42]

Кста логгер у меня тоже отрабатывает нормально, зато вот когда клиент коннектиться почему-то вместо коннекта происходит новы рестарт сервера, чего в коде нет...но логгер пишет именно это


 
Digitman   (2003-10-30 17:23) [43]


> h0use


давай так : мухи - отдельно, котлеты - отдельно

приводи код обработки коннекта клиента на стороне сервера и код ожидания и приема данных от клиента после успешного коннекта


 
h0use   (2003-10-30 17:29) [44]

Сервер:

procedure TBAService.TCPServerExecute(AThread: TIdPeerThread);
var
Client : TSimpleClient;
Msg : String;
St : String[15];
begin
If AThread.Data=nil then Exit;
Msg:= AThread.Connection.ReadLn;
If Msg="" then
begin
AThread.Connection.WriteLn("@Error:Empty String");
exit;
end;
{ Get the clients package info }
Client := Pointer(AThread.Data);
{ Check to see if the clients name has been assigned yet }
if Client.Name = "Logging In" then
begin
{ if not, assign the name and announce the client }
Client.Name := Msg;
if flBaseStat then Client.Permission:=1;
If Client.Permission<>1 then
begin
TCPServerDisconnect(AThread);
Exit;
end;
Athread.Connection.WriteLn("HELLO");
Case Client.Permission of
4: St:="Administrator";
3: St:="Developer";
2: St:="Saler"
end;
SaveLog(2,"+ User "+Client.Name+" from "+Client.DNS + " was logging in as "+St+".");
end;
end;
//--------------------------------------------------------------procedure TBAService.TCPServerDisconnect(AThread: TIdPeerThread);
var
Client : TSimpleClient;
begin
Client := Pointer(AThread.Data);
If Client=nil then Exit;
Clients.Delete(Client.ListLink);
If Client.Permission<>1 then
begin
SaveLog(2,"+ User "+Client.Name+" from "+Client.DNS + " was logging out by server.");
Athread.Connection.WriteLn("@LOGOUT:Server stopped");
end
else
begin
SaveLog(2,"- User "+Client.Name+" from "+Client.DNS + " was kicked out by server.");
SaveLog(2,"! Error: User "+Client.Name+" has no access rights.");
Athread.Connection.WriteLn("@DENY:Database not started");
end;
Client.Free;
AThread.Data := nil;
UpdateClientList;
If Clients.Count<1 then flUserConnected:=False;
end;
//--------------------------------------------------------------procedure TBAService.UpdateClientList;
var
Count : Integer;
begin
for Count := 0 to Clients.Count - 1 do
TSimpleClient(Clients.Items[Count]).ListLink := Count;
end;
//--------------------------------------------------------------procedure TBAService.TCPServerConnect(AThread: TIdPeerThread);
var
Client : TSimpleClient;
begin
Client := TSimpleClient.Create;
Client.DNS := AThread.Connection.LocalName;
Client.Name := "Logging In";
Client.ListLink := Clients.Count;
Client.Thread := AThread;
AThread.Data := Client;
Clients.Add(Client);
flUserConnected:=True;
end;


Клиент:

procedure TForm1.Button1Click(Sender: TObject);
var
Msg,S:String;
begin
TCPClient.Connect(10000);
TCPClient.WriteLn(Edit1.Text);
Msg:=TCPClient.ReadLn(); // Здесь клиент сыпется
if Msg[1]="@" then
begin
S:=UpperCase(Copy(Msg,2,Pos(":",Msg)-2));
If (S="DENY") or (S="LOGOUT") or (S="ERROR")then
begin
ShowMessage(Copy(Msg,Pos(":",Msg)+1,Length(Msg)));
Timer1.Enabled:=False;
TCPClient.Disconnect;
Exit;
end;
end;
ShowMessage(Msg);
end;


 
Digitman   (2003-10-30 17:48) [45]

завтра ... с твоего позволения ... закругляюсь на сегодня


 
h0use   (2003-10-30 17:53) [46]

Я тоже, надеюсь за вечер админы не прибьют тред. если что, то я тебе мыло отправил.


 
Digitman   (2003-10-31 08:17) [47]


if flBaseStat then Client.Permission:=1; //где инициируется flBaseStat = True ?
If Client.Permission<>1 then
begin
// здесь поставь запись в лог
TCPServerDisconnect(AThread); // сильное подозрение, что эта строчка выполняется, ибо Client.Permission = 0
Exit;
end;


а где, спрашивается, происходит присвоение Client.Permission


 
Digitman   (2003-10-31 08:21) [48]


> а где, спрашивается, происходит присвоение Client.Permission


пардон, не Client.Permission, а flBaseStat ?? ведь только при flBaseStat = True это св-во получает значение = 1 !


 
h0use   (2003-10-31 10:02) [49]

flBaseStat - Это флаг запущена БД или нет, но даже если не запущена, то запускается процесс дисконнекта, который сейчас при любом пермишине одинаков, так как клиенту полюбому отправляется сообщение, кторое он должен прочитать, но именно на чтении он и отваливается с ошибкой! Пока весь этот текст крутился в тестовой форме как приложение, все работало 100% без глюков на любом колличестве клиентов, только я это все сунул в сервис, сразу клиент перестал получать данные от сервера.


 
Digitman   (2003-10-31 10:18) [50]


> h0use


ну чего ты демагогию-то развел ? "запущена" БД, "не запущена" ... "глюки", не "глюки"..)

ты помощи просишь в отладке ? значит, делай как тебе говорят, если сам не в состоянии отладить свою логику !

меня интересует, ВЫПОЛНЯЕТСЯ ли сторочка, выделенная жирным !
вот и будь любезен не рассуждать о странностях жизни, а отвечать на четко поставленный вопрос)


 
Digitman   (2003-10-31 10:27) [51]

туту еще одну несуразицу увидел у тебя
ты уверен, что обработчики событий TCPServerConnect/Disconnect выполняются в осн.код.потоке ? Если не уверен, то какое ты имеешь право обращаться из нескольких код.потоков одновременно к списку Clients, не защищенному ни одним объектом синхронизации ? Список-то един для всех код.потоков ! Один код.поток будет добавлять в список элемент, другой в это время удаляет элемент - что получится ? Бардак !


 
h0use   (2003-10-31 10:35) [52]

Жирная строчка выполняется...а про клиентов - это ты прав сейчас бардак, просто я не знаю как синхронизировать. Поэтому периодически вываливается эксепшен.


 
Digitman   (2003-10-31 11:06) [53]

так ... понятно ...

поехали дальше


procedure TBAService.TCPServerDisconnect(...);
begin
try
.. сюда добавь все что у тебя там есть в теле обработчика этого события
except
on E: Exception do
... здесь пиши в лог e.Classname + e.Message ..
end
end;


о результатах записи в лог сообщи


 
h0use   (2003-10-31 11:26) [54]

У меня такое подозрение, что у меня запись в лог не работает, потому как кроме системных сообщений об успешном старте или остановке, других сообщений нет


 
h0use   (2003-10-31 11:31) [55]

Ха..поставил showmessage везде, так блин в сервисе даже TCPServerExecute не запускается


 
Reindeer Moss Eater   (2003-10-31 11:35) [56]

unit LogUnit;

interface

procedure Log(const AMsg:string; const AParam:string = "");

implementation

uses SysUtils;

var LogName:string;

procedure Log(const AMsg : string; const AParam : string = "");
var F:Text;
begin
Assign(F,LogName);
try
if FileExists(LogName) then Append(F) else Rewrite(F);
Writeln(F,FormatDateTime("dd.mm.yyyy hh:mm:ss",Now),#9,AMsg,#9,AParam);
finally
Close(F);
end;
end;

initialization
LogName:=ChangeFileExt(ParamStr(0),".log");
end.


 
Reindeer Moss Eater   (2003-10-31 11:36) [57]

Только не помешает добавить потокобезопастность.


 
Digitman   (2003-10-31 12:15) [58]


> h0use


> Ха..поставил showmessage везде


недопустимо !!!

я же тебе сказал - либо штатный метод TServer.LogMessage() либо MessageBox() вызывай в контрольных точках ! Что непонятного ?

еще раз на огрурцах показываю :


procedure TBAService.TCPServerDisconnect(...);
begin
try
.. сюда добавь все что у тебя там есть в теле обработчика этого события

MessageBox(0, "", "Success", MB_OK or MB_SETFOREGROUND or MB_TOPMOST);

except
on E: Exception do
MessageBox(0, "Исключение !", PChar(e.ClassName + " " + e.Message), MB_OK or MB_SETFOREGROUND or MB_TOPMOST);
end
end;



 
h0use   (2003-10-31 12:28) [59]

Да нет, не то, showmessage то как раз работает, и для отладки нормально, другое дело, что сами процедуры не работают, хотя клиент коннект видит...но сообщения не получает и не отправляет.


 
Reindeer Moss Eater   (2003-10-31 12:42) [60]

Не, не, к терапевту ....


 
h0use   (2003-10-31 12:47) [61]

Да не к терапевту, просто зачем огород городить с messagebox или вообще новый юнит писать, если работает то что тработает. Я понимаю, что не хорошо класть showmessage, но пока это не сказывается на работоспособности его мне легче ставить в критические места (меньше писанины)


 
Digitman   (2003-10-31 12:52) [62]


> h0use


бестолковое, ничем не оправданное и неаргументированное упрямство !

ты хоть что-нибудь слышал о потоконезащищенности VCL ?


 
Digitman   (2003-10-31 12:57) [63]


> h0use


мы тут чем занимаемся вообще ? ищем твои ляпы или плодим новые ошибки в твоей программе ?

еще ракз тебе повторяю - НЕДОПУСТИМО вызывать ShowMessage() в доп.код.потоке !!!!

делай как тебе говорят !!!


 
Digitman   (2003-10-31 13:07) [64]


> h0use


пойми ты, олух царя небесного, что я трачу на исследование твоей проблемы времени, при том что у меня нет ни исходников Инди ни хэлпа перед глазами !

и я понятия не имею, в каких кодовых потоках вызываются обработчики тех или иных событий TCPServer"а !

а ты еще упираешься) ... давным-давным бы уже дал мне детальную инф-цию о том, в каком код.потоке вызываются подозрительные, на мой взгляд, обработчики !


 
h0use   (2003-10-31 13:11) [65]

Сдела как сказали...ничего не изменилось, сообщений не появилось, т.е. как я и предполагал в процедуры соединения Indy сервер не заходит, хотя сокет открывает.


 
h0use   (2003-10-31 13:16) [66]


> Digitman © (31.10.03 13:07) [64]
> пойми ты, олух царя небесного, что я трачу на исследование
> твоей проблемы времени, при том что у меня нет ни исходников
> Инди ни хэлпа перед глазами !


Исходников Инди у меня самого нет, а хелп у них без примеров. Те примеры с их сайта, сами глючные до безумия.


> и я понятия не имею, в каких кодовых потоках вызываются
> обработчики тех или иных событий TCPServer"а !


При старте сервера он создает свой тред, при соединении каждого нового клиента ему создается отдельный поток в котором с ним и работает сервер.


> а ты еще упираешься) ... давным-давным бы уже дал мне детальную
> инф-цию о том, в каком код.потоке вызываются подозрительные,
> на мой взгляд, обработчики !


Могу на мыло выслать весь исходник.


 
Digitman   (2003-10-31 13:35) [67]

о боже ты мой !) дай мне терпения) ...


> h0use © (31.10.03 10:35) [52]
> Жирная строчка выполняется


твои слова ?
о чем это говорит, если, конечно, верить твоим словам ?
о том что метод TBAService.TCPServerDisconnect якобы действительно вызывается !

в теле этого метода - линейный алгоритм
если все тело выполнилось полностью (не важно - с правильной логикой или не правильной !), то выскочит сообщение "Success", иначе (если выполнение тела где-то привело к исключению), то выскочит сообщение "Исключение !".... Т.е. либо одно либо другое сообщение, но обязательно должно появиться !
А если ни одного не появилось, то ты лапшу мне на уши вешаешь, утверждая что (31.10.03 10:35) [52])

А теперь - к чему все это я клоню...
А клоню я к тому, что как только метод TBAService.TCPServerExecute завершит свое исполнение, то по идее сервер должен автоматически разорвать соединение с клиентом. У меня нет хэлпа под рукой, и я в этом не уверен, но у тебя-то он - перед носом !! Ты в состоянии либо сам вчитаться-вникнуть в логику события Execute либо привести это описание сюда дословно ??


 
h0use   (2003-10-31 13:46) [68]

Event handler for peer thread execution.

property OnExecute: TIdServerThreadEvent;

Description

OnExecute is an event handler for TIdServerThreadEvents. OnExecute occurs when a TIdPeerThread attempts to perform the TIdPeerThread.Run method. OnExecute receives AThread as a parameter, representing the TIdPeerThread thread that will be started.

Assign a TIdServerThreadEvent event handler procedure to OnExecute to respond to the event notification.

Use CommandHandlers and CommandHandlersEnabled to provide finer control over commands executed for a peer thread connection.


 
Digitman   (2003-10-31 14:01) [69]


> h0use


судя по описанию, транспортный поток соединения идет на завершение работы после завершения обработки тела OnExecute(), а обработчик этого события вызывается в теле метода TIdPeerThread.Run

где-то после выхода из обработчика OnExecute() соединение с клиентом автоматически разрывается, ибо логика транспортного потока завершена (штатно или по исключению в теле обработчика OnExecute() или в телах вызываемых здесь же п/программ)

итак, я дождусь от тебя наконец-то инф-ции о том, какое сообщение ты видишь ? при исполнении (31.10.03 12:15) [58] ? сколько можно резину уже тянуть ?


 
Reindeer Moss Eater   (2003-10-31 14:05) [70]

А клоню я к тому, что как только метод TBAService.TCPServerExecute завершит свое исполнение, то по идее сервер должен автоматически разорвать соединение с клиентом.

Там иная логика.
С толку сбивает напрашивающаяся аналогия с Сервис.OnExecute когда сервис завершен при выхоже из метода.


 
h0use   (2003-10-31 14:06) [71]

Я же уже писал, никакого, буд-то он вообще не выполняется...ни один контрольный бокс поставленный мной в тобой указанных местах не срабатывает, кроме бокса сигнализируещего, что сервер таки запустился


 
Reindeer Moss Eater   (2003-10-31 14:07) [72]

Digitman
Оставь ты человека.
От тебе незнакомые слова и комбинации таких слов из своего проекта кидает и это ему нравится.


 
h0use   (2003-10-31 14:09) [73]


> Там иная логика.
> С толку сбивает напрашивающаяся аналогия с Сервис.OnExecute
> когда сервис завершен при выхоже из метода.


Если уж на то пошло то там логика как у TThread.execute и когда все это работало не в сервисе то поток сервера прерывался только когда его терминировали (либо ручками либо при "отвале" клиента), и это при всем при том, что OnExecute отрабатывал еще только при логине.


 
Reindeer Moss Eater   (2003-10-31 14:17) [74]

Вот только не надо мне объяснять какая там логика.
Сначала разберись со своим проектом.


 
Digitman   (2003-10-31 14:24) [75]


> Reindeer Moss Eater © (31.10.03 14:05) [70]


> Там иная логика.


я не спорю. может быть и так.
есть еще один вариант - OnExecute вызывается всякий раз когда буфер приема гнезда не пуст

внеси ясность, если код под рукой
внеси так же ясность в реакцию TIdPeerThread на необработанное в теле OnExecute() исключение... код в том виде, в котором он приведен у автора, просто безобразен - нет ни одного блока обработки исключений

факт в том что автор в обработчике OnExecute() ЯВНО вызывает метод OnDisconnect(), это видно из кода, и автор утверждает, что вызов действительно происходит ! но там я, как видишь, расставил ловушки, обойти которые невозможно - хотя бы одна да сработает !

кроме того, если сервер выполняет в какой-то момент времени дисконнект, то обработчик OnDisconnect будет вызван еще раз, автоматически.. а это уже факт, вполне объясняющий отказ 10053 на кл.стороне... но я не вижу вызова тела OnDisconnect() ни явно ни автоматом ! Или он мне лапшу на уши вешать продолжает) ... а мне это уже изрядно поднадоело)


 
Reindeer Moss Eater   (2003-10-31 14:28) [76]

есть еще один вариант - OnExecute вызывается всякий раз когда буфер приема гнезда не пуст

Именно так.
Вот типичный код OnExecute

procedure SomeIndyServerOnExecute(AThread:TidPeerThread);
begin
GlobalStringVar:= GlobalStringVar + Athread.Connection.ReadChar;
if GlobalStringVar = "Пора меня отключать нафик" then AThread.Connection.Disconnect;
end;

Прекращения соединения с клиентом не происходит при выходе из обработчика (если самому не закрыть соединения).


 
h0use   (2003-10-31 14:39) [77]

Господа, я конечно все понимаю, что я туп и глуп, НО я поставил ловушку в самом начале метода OnExecute, и она тоже не сработала! Т.е. В этот метод вообще при коннекте не поадаем. Но когда я весь код один в один перенес в обычную апликацию, все сразу заработало. Можно считать меня тупым, но я не буду начинать писать непонятный для меня сервис, если у меня не отлажена обработка соединения. Так вот, все процедуры приведенные мной работают безошибочно если они работают в обычном приложении, а не в сервисе. Собственно поэтому я и создал тред.


 
Reindeer Moss Eater   (2003-10-31 14:45) [78]

Объясняю твое заблуждение насчет Copy & Paste кода.

Код можно перенести один в один. Но можно забыть перенести таким же методом компонент сервера, от свойств которого работоспособность зависит не меньше чем от кода.

Например:

В gui приложении у сервера не определены CommandHandlers, а в сервисном приложении они есть.
Можно хоть запереноситься кодом туда и обратно, но в сервисном приложении событие OnExecute не возникнет вообще.
И сервис тут совсем ни пришей ни пристегни. Виноваты созданные коммандхендлерс у компонента сервера.


 
Digitman   (2003-10-31 14:52) [79]


> Reindeer Moss Eater © (31.10.03 14:28) [76]


не-а)

вот теперь и ты еще мне лапшу вешаешь)

не поленился я найти этот хваленый Инди и вижу там совершенно иное:



procedure TIdThread.Execute;
begin
try
while not Terminated do try
if Stopped then begin
Suspended := True; // thread manager will revive us
if Terminated then begin
Break;
end;
end;
BeforeRun;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
while not Stopped do begin
Run; //
end;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
finally
AfterRun;
end;
except
on E: exception do begin
FTerminatingException := E.Message;
//уверен, что автор не обрабатывает это событие ! Оно - для Пушкина)
if Assigned(FOnException) then
FOnException(self, E);
//погасили исключение, закругляемся
Terminate;
end;
end;
end;

procedure TIdPeerThread.Run;
begin
try
// пока назначен обработчик, исполняем его
if not Connection.Server.DoExecute(Self) then begin
raise EIdNoExecuteSpecified.Create(RSNoExecuteSpecified);
end;
except
// сюда вываливаемся по любому необработанному исключению в теле OnExecute()
on E: EIdSocketError do begin
case E.LastError of
Id_WSAECONNABORTED, // WSAECONNABORTED - Other side disconnected
Id_WSAECONNRESET:
Connection.Disconnect;
end;
end;
on EIdClosedSocket do ;
else
//сюда, скорей всего, и попадаем, т.к. исключение - не транспортного уровня, где-то просто ляп
raise;
end;
// If connetion lost, stop thread
if not Connection.Connected then begin
Stop;
end;
end;


 
Digitman   (2003-10-31 14:58) [80]

кто-то из вас точно лапшу вешает)

>Жирная строчка выполняется

не мое утверждение - автора !

а выполняется она, будучи вызванная из обработчика OnExecute()

а обработчик OnExecute(), согласно последним "веяниям", не вызывается)))))

лыко-мочало, поехали сначала)

клоунада))



Страницы: 1 2 3 4 вся ветка

Форум: "Система";
Текущий архив: 2004.01.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.63 MB
Время: 0.011 c
1-49478
diMAN
2004-01-06 15:13
2004.01.16
Преобразование произвольной строки в TDateTime


1-49609
The X
2004-01-05 09:36
2004.01.16
Глобальное использование задатчиков вроде DecimalSeparator


14-49714
[NIKEL]
2003-12-21 17:53
2004.01.16
16 в Армию поеду из Норильска в Красноярск


1-49565
Gibon
2004-01-05 20:27
2004.01.16
Как засунуть какой нибудь ресурс в exe шник ???


1-49635
Ilg
2004-01-01 16:29
2004.01.16
Заголовок компонента





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский