![]() |
Connection Closed Gracefully.
Hallo, wie ein paar von euch wissen hab ich ja einen kleinen Server geschrieben der auf einen Linux Debian Vserver laufen soll. Da ich zu doof bin den Server für Linux zu kompilen, habe ich ihn bis jetzt immer mit Wine Emuliert. Das klappte bis jetzt auch sehr gut. Heute habe ich allerdings ein Logfile eingebaut und seitdem klappt er nichtmehr richtig. Okok er klappt garnicht mehr. Sobald jemand connected wird die Verbindung abgebrochen.
Ich poste einen Teil des Sourcecodes:
Delphi-Quellcode:
AssignFile(f, 'log\'+DateToStr(Date)+'.txt');
if FileExists('log\'+DateToStr(Date)+'.txt') then begin Append(f) end else begin Rewrite(f); end; Genau an der Rewrite stelle bleibt er stehen. - Ich habe bereits versucht den Datein die Chmod rechte zu geben. - Ich habe bereits allen Datein und Ordnern testweise 777 gegeben. - ich habe versucht statt log\ einfach mal log/ zu machen - ich habe versucht die Datei manuell zu erstellen. Er springt trozdem zu Rewrite - Ich habe versucht das ganze als Root im Home verzeichnis auszuführen Was kann ich noch tun? P.S. Unter Windows läuft der Server übrigens Problemlos. Edit: Auch wenn sich die Log Datein im gleichen Verzeichnis befinden wie der Server befinden, klappt es nicht. "AssignFile(f, DateToStr(Date)+'.txt');" Edit: Ich glaub ich hab den Fehler gefunden. Ich habe eine Debug Nachicht eingebaut die mir statt 21.12.09 folgendes ausgegeben hat: "File log\12/21/2009.txt existiert nicht" Edit: So ich hab das Problem jetzt gelöst.
Delphi-Quellcode:
Begründung:
procedure TServer.IdTCPServer1Execute(AThread: TIdContext);
var f : TextFile; Files : string; myDate : TDateTime; myYear, myMonth, myDay : Word; begin myDate := Date; DecodeDate(myDate, myYear, myMonth, myDay); Files := ('log\'+IntToStr(myDay)+'-'+IntToStr(myMonth)+'-'+IntToStr(myYear)+'.txt'); AssignFile(f, Files); if FileExists(Files) then begin Append(f) end else begin Rewrite(f); end; Unter Windows gibt Date "21.12.09" aus. Unter Linux jedoch "12/21/2009". Dies führt zu komplikationen bei den Pfadangaben und damit zum Fehler. Lösung: mit DecodeDate das Datum in die Einzelteile aufteilen und anschließend selbst zusammensetzen. Ich habe als Trennzeichen "-" benutzt. Damit erhalte ich Datumsangaben im format "21-12-09". |
Re: Connection Closed Gracefully.
Zitat:
Delphi-Quellcode:
Was gibt hier IOResult aus?AssignFile(f, 'log\' + DateToStr(Date) + '.txt'); if FileExists('log\' + DateToStr(Date) + '.txt') then {$I-} Append(f) else Rewrite(f); {$I+} if IOResult <> 0 then RaiseLastWin32Error; lg. Astat |
Re: Connection Closed Gracefully.
Das Problem ist doch noch nicht so gelöst wie ich dachte.
Delphi-Quellcode:
So sieht meine Konsole aus:
myDate := Date;
DecodeDate(myDate, myYear, myMonth, myDay); Files := ('log\'+IntToStr(myDay)+'-'+IntToStr(myMonth)+'-'+IntToStr(myYear)+'.txt'); AssignFile(f, Files); if FileExists(Files) then begin Append(f); WriteLn('ap'); end else begin Rewrite(f); WriteLn('rw'); end;
Delphi-Quellcode:
Beim ersten durchlauf klappt alles. ( Was mich wundert ist das er Append(f); 2x aufruft.
#######################
## ## ## Masterserver 0.03 ## ## ## ####################### Server wurde initialisiert. Server lauscht auf Port: 5000 ap [2:10:00 AM] Account: fff existiert nicht. ap Beim zweiten durchlauf gibts wieder die Meldung "Connection Closed Gracefully." Er scheint aber dennoch mind. bis "AssignFile(f, Files);" zu arbeiten. Wenn ich da eine WriteLn einbaue, wird diese trozdem noch aufgerufen. Edit: Die Datei wird ordnungsgemäß über Closefile geschlossen. Beim zweiten durchlauf bleibt er bei "Append(f);" stehen. Die Frage die sich stellt: Wieso ruft er "Append(f);" 2x auf. Nirgenswo ist eine schleife einprogrammiert... Edit: Ich poste am besten mal den kompletten Part:
Delphi-Quellcode:
procedure TServer.IdTCPServer1Execute(AThread: TIdContext);
var Data : String; StrArr : TDynStringArray; ini : TIniFile; f : TextFile; Files : string; myDate : TDateTime; myYear, myMonth, myDay : Word; begin with AThread.Connection do begin myDate := Date; DecodeDate(myDate, myYear, myMonth, myDay); Files := ('log\'+IntToStr(myDay)+'-'+IntToStr(myMonth)+'-'+IntToStr(myYear)+'.txt'); AssignFile(f, Files); if FileExists(Files) then begin Append(f); end else begin Rewrite(f); end; Data := String(Socket.ReadLn); Data := Trim(Data); if Length(Data) > 0 then begin StrArr := Explode('|', Data); if StrArr[0] = 'login' then begin if StrArr[3] = Clientver then begin if FileExists('accounts\'+StrArr[1]+'.ini') then begin ini := TIniFile.Create('accounts\'+StrArr[1]+'.ini'); try if StrArr[2] = ini.ReadString('Data','Passwort','') then begin Socket.WriteLn('login'); WriteLn('['+TimeToStr(Time)+']'+' Account: '+StrArr[1]+' hat sich eingeloggt.'); WriteLn(f, '['+TimeToStr(Time)+']'+' Account: '+StrArr[1]+' hat sich eingeloggt.'); end else begin Socket.WriteLn('invalid'); WriteLn('['+TimeToStr(Time)+']'+' Account: '+StrArr[1]+' falsches Passwort.'); WriteLn(f, '['+TimeToStr(Time)+']'+' Account: '+StrArr[1]+' falsches Passwort.'); end; finally ini.free; end; end else begin Socket.WriteLn('na'); WriteLn('['+TimeToStr(Time)+']'+' Account: '+StrArr[1]+' existiert nicht.'); WriteLn(f, '['+TimeToStr(Time)+']'+' Account: '+StrArr[1]+' existiert nicht.'); end; end else begin Socket.WriteLn('version'); end; end; if StrArr[0] = 'register' then begin if FileExists('accounts\'+StrArr[1]+'.ini') then begin Socket.WriteLn('vorhanden'); WriteLn('['+TimeToStr(Time)+']'+' Account: '+StrArr[1]+' existiert bereits.'); WriteLn(f, '['+TimeToStr(Time)+']'+' Account: '+StrArr[1]+' existiert bereits.'); end else begin try ini := TIniFile.Create('accounts\'+StrArr[1]+'.ini'); ini.WriteString('Data','Passwort',StrArr[2]); ini.WriteString('Data','E-Mail',StrArr[3]); finally Socket.WriteLn('erfolg'); ini.free; WriteLn('['+TimeToStr(Time)+']'+' Account: '+StrArr[1]+' wurde registriert.'); WriteLn(f, '['+TimeToStr(Time)+']'+' Account: '+StrArr[1]+' wurde registriert.'); end; end; end; end; end; CloseFile(f); end; Zitat:
"if IOResult <> 0 then RaiseLastWin32Error;" gibt garnichts aus. Der Debugger sagt folgendes: --------------------------- Debugger Exception Notification --------------------------- Project Project1.exe raised exception class EInOutError with message 'I/O error 32'. --------------------------- Break Continue Help --------------------------- |
Re: Connection Closed Gracefully.
Zitat:
Delphi-Quellcode:
2. Das Problem mit dem mehrfachen Aufruf:
DateSeparator := '.';
Delphi-Quellcode:
Ist ein Serverthread, dieser wird auch mehrfach aufgerufen werden können.
procedure TServer.IdTCPServer1Execute(AThread: TIdContext);
Dh. Die Log-Schreiberei und Globalen Variablen müssen Threadsave sein, sonst knallts sowiso irgendwann. Tip: Das Logging in eine Threadsave Funktion auslagern, und mit CriticalSections synchronisieren.
Delphi-Quellcode:
lg. Astat
var
_SyncLog: TRTLCriticalSection; procedure LogWrite(const ALogfile, AMessage: string); var f: TextFile; begin EnterCriticalSection(_SyncLog); try AssignFile(f, ALogfile); try {$I-} if FileExists(ALogfile) then Append(f) else Rewrite(f); if IOResult <> 0 then Reset(f); {$I+} Writeln(f, AMessage); finally CloseFile(f); end; finally LeaveCriticalSection(_SyncLog); end; end; initialization InitializeCriticalSection(_SyncLog); finalization DeleteCriticalSection(_SyncLog); end. |
Re: Connection Closed Gracefully.
Zitat:
Eine einfache Funktion, die einen Dateinamen für Logdateien erstellt, ist doch ausreichend:
Delphi-Quellcode:
Function GetLogFilename() : String;
Var y,m,d : Word; Begin DecodeDate(Now,y,m,d); Result := Format('log\%.2d-%.2d-%.2d.TXT',[y,m,d]); End; |
Re: Connection Closed Gracefully.
Zitat:
Ehrlich gesagt ist mir der Code etwas zu kompliziert. Schon mein Lehrer hat damals immer gesagt kopiere nie was du nicht verstehst :stupid: __________________________________________________ __________ Zitat:
Es scheint so als würde er die Datei nicht richtig schließen, weil ich sie solang der Server läuft auch nicht im Windows öffnen kann. Deshalb habe ich jetzt mal Testweise unter jedes WriteLn ein Closefile geschrieben. Leider ohne erfolg. |
Re: Connection Closed Gracefully.
Delphi-Quellcode:
Sind bei Linux die Pfadbegrenzer nicht '/' anstatt '\' ?
Function GetLogFilename() : String;
Var y,m,d : Word; Begin DecodeDate(Now,y,m,d); Result := IncludeTrailingPathDelimiter('log')+Format('%.2d-%.2d-%.2d.TXT',[y,m,d]); End; |
Re: Connection Closed Gracefully.
Das ganze dürfte durch Wine ausgeglichen werden.
Der Server läuft leider unter Windows genausowenig. |
Re: Connection Closed Gracefully.
Bei deinem Pfad muss solltest Du darauf achten / als Ordnergrenze zu verwenden. Zudem, wenn Du von deinem eigenen Pfad ausgehst, musst fehlt davor ein ./, sodas letztendlich der Pfad folgendermaßen aussieht: ./log/Datum.txt.
|
Re: Connection Closed Gracefully.
Zitat:
Wobei man sowieso keine relativen Pfade nutzen sollte. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:19 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz