![]() |
[Indy 10, TCP] Client->Server Kommunikationsprobleme
Hallo liebe Community!
Erstmal noch Happy New Year nachträglich! Ich bastel grad privat an einem kleinen Spielchen, was ich später auch gern hier + OpenSource veröffentlichen möchte. Allerdings würde ich vorher gern noch den Multiplayer-Part hinbekommen. Single-Player + AI funktioniert schon soweit. :wink: Das ist das erste mal, dass ich konkret was mit Indy mache. Hab daher im Internet rumgeschaut und rumprobiert und ein Netzwerk-Prototyp funktionierte sogar schon recht gut mit einem Kumpel übers Internet. Allerdings hab ich die Kommunikation per String-Commands aufgebaut, so wie ich es auch aus den Tutorials und Demos erstmals gesehen und übernommen hab. Um Traffic zu sparen und damit Latenzzeiten gering zu halten, wollte ich diese Kommunikation nun auf Byte- und Integer-Ebene abstrahieren und statt mit .IOHandler.WriteLn und .ReadLn mit .Write und .ReadBytes arbeiten. Das Problemchen dabei ist, dass die Kommunikation Server->Client klappt. Allerdings streikt jetzt die Kommunikation Client->Server total, obwohl es quasi der gleiche Code ist. Und ich verstehe nicht warum. Ich such schon seit Tagen im Netz, probiere hier und da rum. Aber es klappt nicht so, wie ich's will ... :gruebel: Typ TBroadcastType:
Delphi-Quellcode:
1) Server -> Client:
TBroadcastType = record
Command, Value1, Value2, Value3: Integer; end; PBroadcastType = ^TBroadcastType;
Delphi-Quellcode:
2) Client -> Server:
procedure TXYZObserver.BroadcastServerCommand(Command, Value1, Value2,
Value3: Integer); var cList: TList; Count: Integer; StrCommand: String; EventItem: TBroadcastType; Buffer: TIdBytes; begin EventItem := PrepareBroadcastEvent(Command, Value1, Value2, Value3); StrCommand := BuildServerCommandString (Command, Value1, Value2, Value3); AddLog ('>> Sending Command to Clients: ' + StrCommand); Buffer := RawToBytes(EventItem, sizeof (TBroadcastType)); cList := FXYZServer.Contexts.LockList; try for Count := 0 to cList.Count -1 do with TIdContext(cList[Count]) do Connection.IOHandler.Write (Buffer); finally FXYZServer.Contexts.UnlockList; end; end;
Delphi-Quellcode:
3) Server OnExecute Event:
procedure TXYZObserver.BroadcastEventToServer(Command, Value1, Value2,
Value3: Integer); var StrCommand: String; EventItem: TBroadcastType; Buffer: TIdBytes; begin // ** Client sending Event to Server EventItem := PrepareBroadcastEvent(Command, Value1, Value2, Value3); StrCommand := BuildServerCommandString(Command, Value1, Value2, Value3); AddLog ('>> Sending Command to Server: ' + StrCommand); Buffer := RawToBytes(EventItem, sizeof (TBroadcastType)); // {*1} FXYZClient.IOHandler.WriteLn('TEST'); FXYZClient.IOHandler.Write(Buffer); end;
Delphi-Quellcode:
4) Process Client Incoming:
procedure TXYZObserver.ProcessServerIncomingEvent(AContext: TIdContext);
var EventItem: PBroadcastType; Buffer: TIdBytes; begin {*2} if not AContext.Connection.IOHandler.Connected then Exit; New (EventItem); AContext.Connection.IOHandler.ReadBytes(Buffer, SizeOf (TBroadcastType)); BytesToRaw (Buffer, EventItem^, SizeOf (TBroadcastType)); ReceiveIncomingEvent(EventItem); end;
Delphi-Quellcode:
Die Punkte 1) + 4) funktionieren zusammen so wie gedacht. Allerdings 2) + 3) überhaupt nicht.
procedure TXYZObserver.ProcessClientIncomingEvent;
var SvStrInput: String; EventItem: PBroadcastType; Buffer: TIdBytes; begin if not FXYZClient.Connected then Exit; if FXYZClient.IOHandler.InputBuffer.Size <= 0 then Exit; New (EventItem); FXYZClient.IOHandler.ReadBytes(Buffer, SizeOf (TBroadcastType)); BytesToRaw (Buffer, EventItem^, SizeOf (TBroadcastType)); ReceiveIncomingEvent(EventItem); end; Was passiert ist folgendes: - Ich hab bei {*2} einen Breakpoint gesetzt. - Wenn ich beim Server einen Event auslöse (Bewege von X nach Y), kommt das beim Client an, wird empfangen, verarbeitet, in die Que gehauen und abgearbeitet. So wie gewollt und gedacht. - Wenn ich beim Client allerdings den gleichen Event auslöse, kommt nichts beim Server an. Der Breakpoint wird nicht ausgelöst. Erst wenn ich im Client "spamme", wird er ausgelöst. Allerdings kommt dann bei ReadBytes (und BytesToRaw) nur Müll raus. Nicht das, was ich gesendet hab. - Wenn ich allerdings die Kommentare vor {*1} entferne (und dafür Write auskommentiere), wird sofort bei der ersten Aktion vom Klient, der Breakpoint beim Server ausgelöst. - Beide Programme laufen auf dem selben Rechner. Also zusammengefasst: Arbeite ich mit .ReadLn und .WriteLn, funktioniert alles so wie gedacht. Ersetze ich das durch einen Record (4 Integers), funktioniert nur noch Server->Client, aber nicht mehr Client->Server, obwohl es vom Prinzip der selbe Code ist. Kann mir jemand sagen warum? Wahrscheinlich ists nur ne Kleinigkeit, aber ich seh da nix ... :gruebel: |
Re: [Indy 10, TCP] Client->Server Kommunikationsprobleme
Ich bin mal so frei, zu pushen.
|
Re: [Indy 10, TCP] Client->Server Kommunikationsprobleme
Kann mir da keiner helfen? :pale:
|
Re: [Indy 10, TCP] Client->Server Kommunikationsprobleme
Hi,
wie ist die Kommunikation vom Client zum Server aufgebaut ? Ist die Client-Connection(IdTcpClient) in einem seperaten Thread ? Greetz Data |
Re: [Indy 10, TCP] Client->Server Kommunikationsprobleme
Ich hab rausgefunden, dass Write vom Client zum Server kein OnExecute-Event auslöst.
Wenn man durch WriteLn stept, macht er daraus Write (ABuffer + EOL (= $D$A)). Ergo: Wenn ich meinen Buffer um 2 Bytes erweitere und dort $D$A hinterlege, funktionierts und beim Server kommt das an, was gesendet wurde. Holpert aber immernoch ein bisschen. Jedoch bin ich erstmal einen Schritt weiter. :D |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:39 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