![]() |
AW: Spielwiese - SocketTest
Zitat:
Also ich muss vorweg sagen, ich habe mit TClientSocket/TServerSocket nie gearbeitet, wohl aber mit der dahinterliegenden BSD-Socket bzw. WinSock-API. Dort ist es so, dass die Funktion recv() einen Wert zurückliefert, der angibt, wieviele Bytes tatsächlich gelesen wurde (oder -1 falls keine Bytes gelesen werden konnten oder im Falle eines Fehlers). Ein Rückgabewert von 0 bedeutet, dass die Verbindung geschlossen wurde. Das könnte hier der Fall sein. Das kannst du aber nur herausfinden, indem du tatsächlich ein recv ausführst, ReceiveLength ist irreführend. Wenn du deinen Code nicht überall ändern willst, kannst du einfach 1 Byte lesen und als Flag MSG_PEEK übergeben. So wird das Byte nicht "konsumiert" und der restliche Programmablauf bleibt unbeeinflusst.
Delphi-Quellcode:
var
Dummy: Byte; begin if Socket.ReceiveBuf(Dummy, 1, MSG_PEEK) = 0 then // Verbindung geschlossen; |
AW: Spielwiese - SocketTest
Zitat:
Zitat:
Deine Send-Routine enthält auf jeden Fall das von mir beschriebene Problem, dass ![]() Zitat:
|
AW: Spielwiese - SocketTest
Zitat:
Ich versuche es noch mal in Tabellenform:
Code:
| Verbindung besteht | Verbindung geschlossen
Lesbare Bytes vorhanden | > 0 | -- Keine lesbaren Bytes vorhanden | -1 | 0 Fehler | -1 | -1 (Wie zur Hölle verwendet man den [TABLE]-BBCode? :duck: ) |
AW: Spielwiese - SocketTest
Zitat:
Mein echtes Projekt hatte Indy genutzt, also blocking. Das stelle ich derzeit entsprechend um. Zitat:
Die Datenmengen sind derzeit auch sehr klein, so dass diese kein Problem darstellen sollte. Ich gehe derzeit eher von einem Threading-Problem aus. Aber ich schaue mir das die nächsten Tage nochmal genauer an. Danke Euch! |
AW: Spielwiese - SocketTest
Also das Problem war hausgemacht durch die Umstellung auf Streams und einige kritische Zugriffe durch Threads.
Ich habe das jetzt bereinigt und es läuft augenscheinlich perfekt. Anbei die wesentlichen Auszüge, falls es jemanden hilft. Das komplette Framework werde ich hier nicht hochladen, da es scheinbar nicht sehr von Interesse ist. Falls doch, schreibt eine pm.
Delphi-Quellcode:
procedure ...SendSLTo...(aSL: TStringList);
var MS: TMemoryStream; MSSize: LongInt; begin MS := TMemoryStream.Create; aSL.SaveToStream(MS); MS.Seek(0, soBeginning); MSSize := MS.Size; fClientSocket.Socket.SendBuf(MSSize, SizeOf(MSSize)); fClientSocket.Socket.SendStream(MS); end; procedure ...SocketClientRead(Sender: TObject; Socket: TCustomWinSocket); const BufSize = 1024 * 10; var Len: Integer; Bfr: Pointer; begin GetMem(Bfr, BufSize); repeat Len := Socket.ReceiveBuf(Bfr^, BufSize); if (Len > 0) then fMessageHandlerServer.RegisterInBuffer(Bfr, Len, Socket); until (Len <= 0); FreeMem(Bfr); end; procedure ...RegisterInBuffer(const aBufr: Pointer; const aLen: Integer; const aConnection: TObject); var lMS: TMemoryStream; lSL: TStringList; BreakFlag: Boolean; begin fCS.Enter; try if (aLen > 0) then begin fMS.Seek(0, soEnd); fMS.Write(aBufr^, aLen); end; BreakFlag := False; repeat if (fBlockSize = 0) then begin if (fMSPos + SizeOf(fBlockSize) <= fMS.Size) then begin fMS.Position := fMSPos; fMS.Read(fBlockSize, SizeOf(fBlockSize)); fMSPos := fMS.Position; end; end; if (fBlockSize > 0) then begin if (fMSPos + fBlockSize <= fMS.Size) then begin fMS.Position := fMSPos; lMS := TMemoryStream.Create; lMS.CopyFrom(fMS, fBlockSize); fMSPos := fMS.Position; lSL := TStringList.Create; lMS.Position := 0; lSL.LoadFromStream(lMS); LogSL('<==', '', lSL); RegisterInSL(lSL, aConnection); FreeAndNil(lMS); fBlockSize := 0; end else BreakFlag := True; end else BreakFlag := True; until (BreakFlag); if (fBlockSize = 0) then begin fMS.Clear; fMSPos := 0; end; finally fCS.Leave; end; end; procedure ...DoRegisterInSL(out aDone: Boolean); var lSL: TStringList; lMessage: IsoMessage; lConnectionStringList: IsoConnectionStringList; lConnection: TObject; begin aDone := False; lConnectionStringList := fMessageStringList.GetNextConnectionStringList; if Assigned(lConnectionStringList) then begin lConnection := lConnectionStringList.Connection; lSL := lConnectionStringList.GetNextSL; if Assigned(lSL) then begin if Assigned(fMessageImporter) then begin fMessageImporter.ResolveSLToMessage(lSL, lConnection, lMessage); if Assigned(lMessage) then begin fInMessageList.Add(lMessage); aDone := True; end; end; FreeAndNil(lSL); end; end; end; |
AW: Spielwiese - SocketTest
Bei dem letzten veröffentlichten Stand gibt es noch Probleme bei umfangreichen gleichzeitigen Zugriffen durch mehrere Clients, da bis dahin nur ein Puffer für eingehende Streams verwendet wurde.
Das nur als Info, falls jemand bei Tests Probleme bekommt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:09 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