![]() |
TCPServer Client daten verarbeiten
Hallo es geht um einen Client der anscheintnach Binary code zum Server sendet bzw Bytes / Buffer
Ich möchte diese Bytes / Buffers verarbeiten aber wie fange ich an? Also im Readln ist nix womit ich dem client eine Antwort schicken könnte. Ich arbeite schon länger mit delphi habe mich jedoch in dem Sinne noch nie beschäftigt :D Ich wär sehr dankbar über Antworten :) Edit:
Delphi-Quellcode:
das kommt raus wenn ich das z · • € : ¸ = « ‡ $ ° k ¥ A È
Delphi-Quellcode:
mache
if AContext.Connection.Connected then
begin memo1.Lines.Add(AContext.Connection.IOHandler.ReadString(1)); end; |
Re: TCPServer Client daten verarbeiten
Hallo danu1104, bist Du Server und oder Client?
Was verstehst Du unter, "Daten weiterverarbeiten"? Hast Du schon Code? Beschreib das alles bitte mal genauer, mann kennt sich da nicht recht aus, was Du eigentlich willst. lg. Astat |
Re: TCPServer Client daten verarbeiten
Ich bin der Server und will von einem Client den ich natürlich nicht geschrieben habe die Login commands wissen (ich will nix hacken oder beschädigen)
bisher habe ich nur das was ich angegeben habe versucht weil ich ja auch schon mit indy arbeite, ging ich davon aus mit ReadLn alle information zu erhalten: ausschnit aus einem programm von mir:
Delphi-Quellcode:
so ungefair, aber anscheint arbeitet dieser mit bytes und buffer das heisstcomline:=TSTringlist.Create; comline.Delimiter:=';'; comline.DelimitedText:=AThread.Connection.IOHandler.ReadLn(); if (comline.Strings[0] = '@KILLLOGIN') then begin Items.Caption:= '« Command '+comline.Strings[0]+' incoming ...'; if KillProcess(ExtractFilename(Login_BIN)) then begin AThread.Connection.IOHandler.WriteLn('CLOSED') end else begin AThread.Connection.IOHandler.WriteLn('FAIL') end; end; ich bin einwenig überfordert und habe paar fragezeichen aufn kopf ^^ :D Meine frage, wie verarbeitet man bytes oder buffer, bzw wie finde ich raus um welchen typ stream es sich hier handelt. ich kann ja mit der o.g. ausgabe nicht wirklich was anfangen , kann man es irgendwie decodieren? Edit: Es wär sehr hilfreich da ich ein eigenes MMOG an bastel bin und schwierigkeiten mit dem World Server habe als der der es möglich macht das 2 Player sich gegenüberstehen können, nur hatte ich bis jetzt das problem gehabt das beim schreiben der coordinaten in der Database entweder exception error kam oder das spiel eingefrohren ist. Und um das Problem zu lösen wollte ich mal schaun wie andere es gemacht haben ohne illegale action wie zb source decomplieren ich habe einen Session/ Messanger und hier den world:
Delphi-Quellcode:
der nicht wirklich will
program MounttaSrv;
{$APPTYPE CONSOLE} uses Forms, SysUtils, IdBaseComponent, IdComponent, IdTCPServer, idcontext, IdAntiFreezeBase, IdAntiFreeze, inifiles, Variants, Classes, keyboard; type TServer = class(TIdTCPServer) Procedure ExecuteSettings; procedure DBServerConnect(AContext : TIDContext); procedure DBServerDisconnect(AContext : TIDContext); procedure DBServerExecute( AContext: TIdContext); Function RunCommand(cmd,dir:string):string; private IfEnd :Boolean ; Clients:Integer; { Private-Deklarationen } public { Public-Deklarationen } end; var DBServer:TServer; INI:TIniFile; InCom2,Sett:TStringlist; Procedure TServer.ExecuteSettings; Var I:Integer; T:TextFile; S:TStringList; begin Sett:=TStringlist.Create; S:=Tstringlist.Create; S.LoadFromFile(ExtractFilePath(Paramstr(0))+'config.ini'); sett.Delimiter:=','; Sett.DelimitedText:=s.Text; for i := 0 to Sett.Count -1 do begin if Sett.Strings[i] = 'Mountara_Port' then begin DBServer.DefaultPort:=StrToInt(Sett.Strings[i+1]); end; if Sett.Strings[i] = 'Mountara_ListenQueue' then begin DBServer.ListenQueue:=StrToInt(Sett.Strings[i+1]); end; if Sett.Strings[i] = 'Mountara_Max_Connections' then begin DBServer.MaxConnections:=StrToInt(Sett.Strings[i+1]); end; end; end; procedure TServer.DBServerDisconnect(AContext : TIDContext); begin DBserver.Clients:=DBserver.Clients-1; WriteLn('» A User is Disconnected. ID ( ',AContext.Connection.Greeting.ID,' )'); WriteLn('»» Clients Online: ',DBserver.Clients) end; procedure TServer.DBServerConnect(AContext : TIDContext); begin DBserver.Clients:=DBserver.Clients+1; WriteLn('» A User is Connected. ID ( ',AContext.Connection.Greeting.ID,' )'); WriteLn('»» Clients Online: ',DBserver.Clients) end; Function TServer.RunCommand(cmd,dir:string):string; Var Ini:Tinifile; Op,Cm:TStringlist; begin Op:=TStringlist.Create; Op.Delimiter:=' '; Op.DelimitedText:=CMD; if Op.Strings[0] = 'GET' then begin Op.Delimiter:=':'; Op.DelimitedText:=CMD; Ini:=Tinifile.Create(ExtractFilePath(Paramstr(0))+dir+'\'+Op.Strings[1]+'.mdb'); Cm:=TStringlist.Create; Cm.Delimiter:=':'; Cm.DelimitedText:=Op.Text; if not ini.SectionExists(Op.Strings[1]) then begin WriteLn('» Datenbank Error:'+#13+'Eintrag konnte nicht gefunden werden! Setzen Sie den eintrag mit dem "SET" befehl.') ; WriteLn('»»'); end else result:=ini.ReadString(Op.Strings[1],Cm.Strings[2],''); end else if Op.Strings[0] = 'SET' then begin Op.Delimiter:=':'; Op.DelimitedText:=CMD; Ini:=Tinifile.Create(ExtractFilePath(Paramstr(0))+dir+'\'+Op.Strings[1]+'.mdb'); Cm:=TStringlist.Create; Cm.Delimiter:=':'; Cm.DelimitedText:=Op.Text; try if Cm.Count < 4 then begin WriteLn('» Datenbank Error:'+#13+'Kein oder Falsch angegebener wert.') ; WriteLn('»»'); Exit; end else ini.WriteString(Op.Strings[1],Cm.Strings[2],Cm.Strings[3]); finally WriteLn('» Datenbank: eintrag '+ Cm.Strings[2]+' '+Cm.Strings[3]+' in '+Cm.Strings[1]+' war erfolgreich.'); WriteLn('»»'); end; end else begin WriteLn('» Datenbank Error:'+#13+'Solchein befehl ist mir nicht bekannt.'); WriteLn('»»'); end; ini.free; end; procedure TServer.DBServerExecute( AContext: TIdContext); Var S,Player:String; Val:Integer; sVal:String; begin if AContext.Connection.Connected then begin InCom2.DelimitedText:=AContext.Connection.IOHandler.ReadLn(); // START // AContext.Connection.Socket. Player:=IntToStr(AContext.Connection.Greeting.Index); s:='SET ONLINEUSER:ENTRYS:1'; RunCommand(S,'share\users'); If InCom2.Strings[0] = 'GETENTRYS' then begin AContext.Connection.IOHandler.WriteLn('OnlinePlayers,'+Player); end else If InCom2.Strings[0] = 'GETPOSX' then begin S:='GET ONLINEUSER:POSX'+InCom2.Strings[1]; sval:=RunCommand(S,'share\users'); AContext.Connection.IOHandler.WriteLn('POSX,'+sval); end else If InCom2.Strings[0] = 'GETPOSY' then begin S:='GET ONLINEUSER:POSY'+InCom2.Strings[1]; sval:=RunCommand(S,'share\users'); AContext.Connection.IOHandler.WriteLn('POSY,'+sval); end else If InCom2.Strings[0] = 'GETPOSZ' then begin S:='GET ONLINEUSER:POSZ'+InCom2.Strings[1]; sval:=RunCommand(S,'share\users'); AContext.Connection.IOHandler.WriteLn('POSZ,'+sval); end; If InCom2.Strings[0] = 'SETPOSX' then begin S:='SET ONLINEUSER:POSX1:'+InCom2.Strings[1]; sval:=RunCommand(S,'share\users'); end; If InCom2.Strings[0] = 'SETPOSY' then begin S:='SET ONLINEUSER:POSY1:'+InCom2.Strings[1]; sval:=RunCommand(S,'share\users'); end; If InCom2.Strings[0] = 'SETPOSZ' then begin S:='SET ONLINEUSER:POSZ1:'+InCom2.Strings[1]; sval:=RunCommand(S,'share\users'); end; END; end; Procedure CreateServ; Var i:Integer; begin WriteLn('»» ----------------------------------------------------------------'); WriteLn('»»',' PSDsoft Productions: 2007 - 2009. '); WriteLn('»» ----------------------------------------------------------------'); WriteLn('»»'); WriteLn('»» ',Application.Title); WriteLn('»»'); InCom2:=TStringlist.Create; DBServer:=TServer.Create(nil); DBServer.OnExecute:=DBServer.DBServerExecute; DBServer.OnDisconnect:=DBServer.DBServerDisconnect; DBServer.OnConnect:=DBServer.DBServerConnect; DBserver.Clients:=0; InCom2.Delimiter:=','; try DBServer.ExecuteSettings; except WriteLn('»» Error: Config - File is Missing.'); Exit; end; WriteLn('»» Set Server Port: ',IntToStr(DBServer.DefaultPort)); Sleep(20); try DBServer.Active:=true; Sleep(20); finally if DBServer.Active then WriteLn('»» Set Server Start ....'); WriteLn('»»'); WriteLn('»» Clients: ',DBserver.Clients); end; end; var Key:String; begin Application.Title:='Mounttara World Server'; try try CreateServ; finally key:=keyboard.VirtualKeyCodeToKeyName(keyboard.KeyPressed()); repeat ReadLn; until not true end; except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; end. |
Re: TCPServer Client daten verarbeiten
Zitat:
Wenn Du nun den Buffer gefüllt hast, ziehst Du rückschlüsse auf das Protokoll. z.B. im Buffer sind 19 Byte, wir nehmen mal willkürlich ein Protokoll an, dass wie folgt aufgebaut ist. 4 Byte Länge der Daten + 4 Byte MsgID = 8 Byte, verbleiben 11 Byte. Jetzt überprüfen wir ob diese Annahme stimmt? Wir kopieren die ersten 4 Byte aus dem Buffer in eine integer Variable (iLen).
Delphi-Quellcode:
Wenn der Wert der integer Variable nun 11 Byte anzeigt, haben wir den Header geknackt.
move(Buffer^, iLen, SizeOf(Integer));
Dann werden die nächsten 4 Byte kopiert, und wir sehen die ID oder sonst ein Integer Logon Commando etc.? Wenn der ermittelte Wert unserer integer Variable(n) undefinierte Werte liefert, müssen wir noch ein Byteshifting aller Networkorder durchführen.
Delphi-Quellcode:
Der Header kann auch geringfügig anderst aufgebaut sein, hier heisst es einfach durchprobieren.
iLen := ntohl(DataRec.cbData);
lg. Astat |
Re: TCPServer Client daten verarbeiten
Hört sich gut an was mache ich aber damit genau jetzt?
alles was ich momentan habe ist das:
Delphi-Quellcode:
ich wär jetzt so naiv und würde wahrscheinlich alles falsch machn und so würde es dan aussehen
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin if AContext.Connection.Connected then begin memo1.Lines.Add(AContext.Connection.IOHandler.ReadString(1)); end; end;
Delphi-Quellcode:
dann würde ich wohl fragen was falsch ist, ich entschuldige mich für mein bissen wissen was ich habe und hoffe doch das du mir da helfen kannst, ich finde es auf jedenfall toll das du bereit bist mir zu helfen. klasse! :thumb:
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin if AContext.Connection.Connected then begin move(Buffer^, iLen, SizeOf(Integer)); end; end; Edit: Habe folgende optionen mit indy: ![]() |
Re: TCPServer Client daten verarbeiten
Zitat:
Noch ein Tip: Folgende Variablen sind nicht THreadsave, daher kommen auch Deine Probleme mit dem Server wenn mehr als ein Client gleichzeitig connected sind.
Delphi-Quellcode:
INI:TIniFile;
InCom2,Sett:TStringlist; lg. Astat |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:41 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