Verwendung von Delphi zum Einrichten von Kommunikations- und Datenaustauschservern – Analyse der Transceiver-Technologie (Teil 2) Autor: 火鸟 [email protected] 2. Detaillierte Erläuterung des Transceiver-Dienstes 1. Zusammenfassung der Transceiver-Service-Analyse Der Transceiver-Service ist die Kernkomponente des Transceiver-Systems. Er ist dafür verantwortlich, die von der Transceiver-Konsole festgelegten Port- und Kanaldefinitionen aus der Systemkonfigurationsbibliothek zu lesen und Kommunikationsports und ihre Beziehungen während der Laufzeit dynamisch zu erstellen und zu steuern und Steuerung von Daten. Empfangen, Senden und Puffern, Verwalten von Protokollen und Warteschlangen usw. Transceiver Shell ist die Implementierung aller Arten von Ports, die zum Senden und Empfangen von Daten unterstützt werden. 2. Zusammenfassung des Transceiver-Service-Designs Der Transceiver-Service wird aus der Service-Anwendung in Delphi entwickelt. Die Service-Anwendung kann im Systemmodus statt im Benutzermodus ausgeführt werden. Der Service Control Manager (SCM) des Betriebssystems ist für die Betriebsverwaltung des Programms verantwortlich und gehört zum Hintergrundprogramm. Der Transceiver-Kernel ist eine Reihe von Methoden der Transceiver-Klasse, die die Transceiver-Shell einrichten und steuern, und die Transceiver-Shell ist eine Sammlung von Objekten, die für die Kommunikation verantwortlich sind. Hinweis: Aus Leistungs- und Lastgründen implementiert der Transceiver-Kernel die funktionale Aufteilung im Architekturdiagramm nur logisch und die einzelnen Module werden nicht vollständig objektbasiert implementiert. 3. Zusammenfassung der Transceiver-Dienstimplementierung i. Wählen Sie NEU|Andere... aus dem Delphi-Hauptmenü Datei... und wählen Sie NEU|Dienstanwendung im Popup-Dialogfeld Neue Elemente Framework ist wie folgt: PROgram Project1; nutzt SvcMgr, Unit1 in 'Unit1.pas' {Service1: TService};{$R *.RES}begin Application.CreateForm(TService1, Service1); Application.Run;end.unit Unit1;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs;type TService1 = class(TService) private { Privatdeklarationen } public function GetServiceController: TServiceController; end;var Service1: TService1;implementation{$R *.DFM}Prozedur ServiceController(StrgCode: DWord); stdcall;begin Service1.Controller(StrgCode);end;function TService1.GetServiceController: TServiceController;begin Ergebnis := ServiceController;end;end Sie können sehen, dass TService1 zusätzlich zum SvcMgr, der für die Dienstverwaltung verwendet wird, auf die in der Einheit „uses“ verwiesen wird, von TServiced anstelle von TForm, einer überladenen GetServiceController-Funktion und dem im stdcall-Modus aufgerufenen ServiceController-Prozess erbt, mit dem es erstellt wird Delphi Es gibt nicht viel Besonderes an einem Serviceprogramm, Delphi-Fans möchten vielleicht noch einmal jubeln, das ist der mächtige Charme von Delphi RAD. Da die Serviceanwendung außerdem nicht direkt zur Laufzeit debuggt werden kann und über keine Benutzeroberfläche verfügt, sollte während der Entwicklung eine schnittstellenlose Ausgabe von Debugging-Informationen in Betracht gezogen werden, um das Debuggen und die Fehlerbehebung zu erleichtern. ii. Um eine Port-Klasse zu erstellen, die bestimmte Anforderungen erfüllt, und den Transceiver-Kernel mit einem einheitlichen Betriebs- und Verarbeitungsmechanismus zu verwenden, müssen die Ports in der Transceiver-Shell über einheitliche Verarbeitungsregeln verfügen Entwicklungsumgebung (z. B. TCP, FTP usw.) und einige nicht (z. B. MSMQ, Datei usw.) Zu diesem Zeitpunkt müssen Sie eine Klasse erstellen, die Ihren Anforderungen entspricht. Zum Beispiel: type//Da keine Benutzeroberfläche vorhanden ist, wird sie von TComponent anstelle von TControl geerbt. TFilePort=class(TComponent) private FilePath:string;//Den Ordnerspeicherort der Datei abrufen oder speichern Prefix:string;//Datei prefix suffix:string; //File suffix end; Nach der Einrichtung der TFilePort-Klasse kann der Transceiver-Kernel eine einheitliche Klassenverarbeitungsmethode verwenden, um auf bestimmte Dateien aus dem durch FilePath angegebenen Ordner zuzugreifen. Bei Verwendung als Quelle werden Dateien, die die Bedingungen erfüllen, aus einem bestimmten Ordner abgerufen. Bei Verwendung als Ziel werden die von der entsprechenden Quelle erhaltenen Daten in die angegebene Datei geschrieben (tatsächlich). Die tatsächlichen Parameter jedes Portobjekts stammen aus Definition der Porttabelle in der Systemkonfigurationsbibliothek). Ein weiteres Beispiel: Typ TCOMPort=class(TComponent) private ComFace:string;//COM-Schnittstelle zum Abrufen oder Senden von Datenend; TCOMPort wird verwendet, um Daten von der angegebenen COM-Komponentenschnittstelle abzurufen oder an diese zu senden. In Delphi ist die OleVariant-Klasse eine der Möglichkeiten, COM-Komponentenaufrufe zu implementieren. Die Notwendigkeit der Verwendung der TCOMPort-Klasse besteht darin, dass Transceiver die von TCOMPort definierte COM-Schnittstelle nur dann in ein OleVariant-Objekt instanziiert, wenn der erforderliche Datenzugriff erforderlich ist wird nach der Verwendung freigegeben. Dies kann den Lastdruck auf Transceiver und COM-Server verringern. Die gleichen Überlegungen gelten auch für andere ähnliche Komponenten. Das hier vom Autor bereitgestellte Klassenbeispiel ist nur ein Modell, und bei Bedarf sollten entsprechende Methoden und Ereignisse hinzugefügt werden. Zu den vom Autor während der Entwicklung implementierten Klassen gehören: TCOMPort, TMSMQPort, TDBPort, TFilePort usw.iii. Unterstützung für mehrere Kanäle – ein Array von Objekten, die Ports deklarieren. Der Transceiver betrachtet einen Kommunikationsprozess als einen Datenflussprozess von der Quelle zum Ziel. Ein solcher Prozess ist ein Kanal im Transceiver, und dieser Kanal besteht aus mindestens zwei Ports (einer für Quelle und einer für Ziel). Wenn Sie also eine unbegrenzte Anzahl von Kanälen definieren möchten, die frei mit Quelle und Ziel kombiniert werden können, müssen Sie diese separat für Quelle und Ziel deklarieren. Arrays von Objekten verschiedener Port-Klassen (und entsprechende Beziehungen für sie herstellen, wie Sie später sehen werden). Zum Beispiel: private { Private Deklarationen }TCPSource:array of TServerSocket;//Object array for TCP Source TCPTarget:array of TClientSocket;//Object array for TCP Target MailSource:array of TIdPOP3; //For Mail Source Object array MailTarget:array of TIdSMTP; //Objektarray für Mail-Ziel fileSource:array of TFilePort; //Objektarray für Dateiquelle fileTarget:array von TFilePort; //Objektarray für Dateiziel comSource:array von TCOMPort; //Für COM-Zielobjektarray Hinweis: Die Port-Betriebsregeln für Quelle und Ziel desselben Typs sind völlig unterschiedlich, sie werden im Transceiver-Konzept als völlig unterschiedliche Objekte ohne direkte Beziehung betrachtet. Daher werden für denselben Porttyp auch Objektarrays getrennt nach Quelle und Ziel erstellt. iv. Instanziieren Sie das Objektarray zur Laufzeit. Die Anzahl der Elemente in jedem Objektarray wird von Port Builder zur Laufzeit verwaltet. Wenn der Benutzer einige Ports eines bestimmten Typs über die Transceiver-Konsole definiert, instanziiert der Port Builder sie entsprechend ihrer Anzahl und entsprechende Parameter. Andernfalls wird das Objektarray nicht instanziiert. Im Quelltyp-Port-Objekt ist die Name-Eigenschaft auf die Form „Empfangen“+Port-ID festgelegt. Dies hilft dem Datenverteiler, das Objekt zu finden und verschiedene Arten von Port-Objekten einheitlich zu planen. Das Tag-Attribut wird verwendet, um dem Channel Controller die Ziel-ID-Informationen des Channels bereitzustellen, in dem er sich befindet. Das Folgende ist der Instanziierungsteil des comSource-Objektarrays im Port Builder begin //COM erstellen/ Empfangsport itmp:=high(comSource)+1;// Holen Sie sich die aktuelle maximale Anzahl von comSource, itmp ist die ganzzahlige Variable SetLength(comSource ,itmp +1); // Ein comSource-Array-Mitglied hinzufügen comSource [itmp]:=TCOMPort.Create(self); // Das Mitglied instanziieren comSource[itmp].Name:= 'Receive'+inttostr(isource); //Setzen Sie das Name-Attribut auf 'Receive'+Port ID, und isource ist die aktuelle PortID des Integer-Typs comSource [itmp].Tag:= itarget; //Setzen Sie es auf das Ziel ID des Kanals, in dem es sich befindet. NullTest :=rece.Fields['Address'].value;//Den Wert der Systemkonfiguration COMFace abrufen, NullTest ist eine Variant-Variable, wenn (NullTest <>null) und (trim(NullTest)<>'') then begincomSource [itmp].ComFace:=NullTest; //ComFaceNullTest gültige Werte zuweisen:=rece.Fields['interval'].value; //Das Triggerzeitintervall für COM-Objekte zum Abrufen von Daten in der Systemkonfiguration abrufen SetTimer(application.handle,isource,NullTest*60000 ,nil); //Einrichten einer Triggeruhr für den aktuellen Port zum regelmäßigen Sammeln von Daten, isource ist Port IDendelsecomSource [itmp].Tag:=-1;//Initialisierung fehlgeschlagen, als ungültig markiert Port Ende; comSource ist der Quellklassen-Port, der zum Aufrufen der in ComFace definierten Schnittstelle und zum Abrufen von Daten nach einem bestimmten Zeitintervall verwendet wird, entsprechend comTarget Die Implementierung ist Ähnlich, außer dass die Übermittlung von Daten an ComFace oder comTarget ein Echtzeitprozess ist, sodass kein Triggerintervall verwendet werden muss und die beiden Anweisungen zum Festlegen der Uhr weggelassen werden können. Die Erstellung und Initialisierung anderer Arten von Portobjekten ist ähnlich. Zum Beispiel ein weiteres MailTarget-Implementierungsfragment: begin //Create SMTP/Send Port itmp:=high(MailTarget)+1; SetLength(MailTarget,itmp+1); itmp].Name:='send'+ inttostr(itarget); MailTarget[itmp].Tag:=3;//Als Ziel-Port-Typ-Identifikation festlegen NullTest:=rece.Fields['Address'].value; //Mail-Server-Adresse if (NullTest <>null) und (trim(NullTest) <>'') then MailTarget[itmp].Host :=NullTest else bValid:=false; NullTest:=rece.Fields['Port'].value; //Mail-Server-Port if NullTest <>null then(if NullTest<>0 then MailTarget[itmp].Port :=NullTest)else bValid:=false; =rece.Fields['user'].value;//Login-Benutzername, wenn NullTest <>null thenMailTarget[itmp].UserId :=NullTest else bValid:=false; NullTest:=rece.Fields['password'].value;//Login-Passwort………………………end;Vielleicht haben Sie so etwas wie Ich habe einige Zweifel. Eine große Anzahl von Transceiver-Shell-Kommunikationskomponenten wird zur Laufzeit erstellt. Wird die Leistung des Transceiver-Dienstes hoch sein? Tatsächlich ist die Mission des Port Builders einmal abgeschlossen, wenn das ServiceCreate-Ereignis auftritt. Die Anzahl der Shell-Ports wirkt sich nur auf die Initialisierungsgeschwindigkeit des Transceiver-Dienstes aus Natürlich werden die Systemressourcen nicht beeinträchtigt. Es könnte etwas mehr beanspruchen. v. Dynamische Zuordnung und Verarbeitung von Ereignissen. Verwenden Sie unter mehreren von Transceiver Shell unterstützten Kommunikationsports TServerSocket (möglicherweise bevorzugen Sie die Verwendung der Kommunikationskomponente von Indy, dies verstößt jedoch nicht gegen die Designidee des Transceiver Service, sondern ist lediglich eine Modifikation am Auf Shell-Ebene (oder gerade hinzugefügt) ist die implementierte TCP-Quelle ausgeprägter, da sich TServerSocket als Quellport von Objekten wie COM oder POP3 unterscheidet, die regelmäßig ausgelöst werden müssen. Es befindet sich im Transceiver Der Dienst befindet sich nach dem Start immer in einem Überwachungszustand. Es handelt sich um eine Komponente, die entsprechende Ereignisse generiert, wenn ein ClientSocket eine Verbindung herstellt und Daten sendet. Das Folgende ist das Instanziierungsfragment von TCPSource: begin //Create TCP/Receive Port itmp:=high(TCPSource)+1;SetLength(TCPSource,itmp+1); TCPSource [itmp]:=TServerSocket.Create(self); [ itmp].OnClientRead:=TCPServersClientRead;//Weisen Sie den Verarbeitungsprozess des OnClientRead-Ereignisses TCPServersClientRead TCPSource zu [itmp].OnClientError:=TCPServerClientError;//Weisen Sie den Verarbeitungsprozess des OnClientError-Ereignisses TCPServerClientErrorTCPSource zu. [itmp].Name:= 'Receive'+inttostr(isource); //Setzen Sie die Name-Eigenschaft auf 'Receive'+Port ID TCPSource [itmp ].Tag:=itarget; //Legen Sie die Ziel-IDTCPSource seines Kanals fest [itmp].Socket.Data:=@ TCPSource [itmp].Tag;//Hänge die Ziel-ID dieses Port-Objekts als Zeigerdaten an …………………………Kommen Sie zurück und schauen Sie sich die Verarbeitung unserer comSource an Es wird eine Triggeruhr eingerichtet, aber wie soll mit den Ereignissen umgegangen werden, wenn die Uhr ausgelöst wird? In gleicher Weise handelt es sich auch um die dynamische Zuordnung der Ereignisverarbeitung. Die Verarbeitungsdefinition der Uhr von comSource kann zur Ereignisverarbeitung von ServiceCreate hinzugefügt werden: application.OnMessage:=Timer; um die Überlastung der Nachrichtenverarbeitung zu implementieren, wird der Timer ausgelöst Filtern Sie die Verarbeitung. Mit der von der Uhr ausgelösten WM_TIMER-Nachricht können Sie die Datenerfassungsmethode eines bestimmten Quellports entsprechend der Port-ID und dem Typ aufrufen: Prozedur TCarrier.Timer(var Msg: TMsg; var Handled: Boolean);var stmp:string; Obj:TComponent;begin if Msg.message =WM_TIMER then//Verarbeitung der Uhrnachricht begin//Suchen Sie das Objekt, das diese Nachricht entsprechend der Port-ID definiert, die die Nachricht ausgelöst hatObj:=FindComponent(' Receive'+inttostr (Msg.WParam)); if obj=nil then exit;//Verarbeitung beenden, wenn nicht gefunden stmp:=obj.ClassName;//Reflect, um die Typinformationen dieses Port-Objekts zu erhalten, wenn stmp='TIdPOP3' then GetPOP3(TIdPOP3(Obj)); if stmp='TIdFTP(obj)); if stmp='TFilePort' then GetFile(TFilePort(Obj)); if stmp='TCOMPort' then GetCOM(TCOMPort(Obj));// Rufen Sie den Datenerfassungsprozess von COMSource auf…………………… end;end; vi. Das Folgende ist der Datenerfassungsvorgang von COMSource TCarrier.GetCOM(COMObj: TCOMPort);var stmp:string;begin try//Erstellen Sie ein COM-Komponentenobjekt basierend auf dem Wert von ComFace COMInterface:=CreateOleObject (COMObj.ComFace); stmp:=COMInterface.GetData; //Rufen Sie die vereinbarte Schnittstellenmethode auf, um Daten abzurufen, während stmp<>#0 do // #0 ist das vereinbarte Datenextraktions-Endflag begin DataArrive(stmp, COMObj.Tag); // wird zur einheitlichen Verarbeitung an den Daten-Dispatcher übergeben, COMObj.Tag ist die Ziel-Port-ID des Kanals, in dem sich das Objekt befindet stmp:=COMInterface.GetData; end ; COMInterface:= Nicht zugewiesen; außer COMInterface:= Nicht zugewiesen; Schließen Sie den Datenextraktionsvorgang ab und geben Sie das Komponentenobjekt bis zum nächsten Triggeraufruf frei. Das Folgende ist die Datenerfassungsverarbeitung von TCPSource: procedure TCarrier.TCPServersClientRead(Sender: TObject; Socket:TCustomWinSocket);beginDataArrive(socket.ReceiveText,integer(TServerWinSocket( sender).data ^));//Links zum Daten-Dispatcher für eine einheitliche Verarbeitung, Der zweite Parameter ist der Ziel-Port-ID-Zeigerwert, der an den Absender des Socket-Objekts angehängt ist. Verschiedene Arten von Quell-Port-Objekten empfangen Daten auf unterschiedliche Weise, aber letztendlich werden die empfangenen Daten an den Daten-Dispatcher übergeben. Auf der Implementierungsebene wird jedes Mal, wenn ein Datenempfangsobjekt hinzugefügt und sein Datenempfang implementiert wird, ein neuer Quellport für die Transceiver-Shell implementiert. Hinweis: Der Autor implementiert hier nur den Empfang von Textdaten. Benutzer müssen möglicherweise Speicherobjekte, Datenströme oder Binärdaten empfangen und nur geringfügige Änderungen am Empfangscode vornehmen. vii. Datenplanung Die Datenplanung des Transceiver-Dienstes wird durch die logische Einheit des Daten-Dispatchers durchgeführt. Die Hauptaufgabe des Daten-Dispatchers besteht darin, die von verschiedenen Quellports empfangenen Daten einheitlich zu verwalten und zu steuern und mit dem Kanal-Controller zusammenzuarbeiten . Überwachen Sie anhand des Kanals die Datenverteilung an verschiedene Zielports, ob die Sendeergebnisse erfolgreich sind, und entscheiden Sie anhand der Sendeergebnisse und Einstellungen, ob die Daten zur Pufferung und Protokollverarbeitung an den Warteschlangenmanager und Protokollrekorder übermittelt werden müssen der Systemkonfigurationsbibliothek. Schauen Sie sich als nächstes die DataArrive-Methode zum Senden von Daten durch den Quellport an: procedure TCarrier.DataArrive(sData:String;PortID:Integer);var dTime:Datetime:integer; bSendSeccess:Boolean;begin if sData='' then exit;/ / Wenn die Daten leer sind, springe heraus iLogID:=-1; dTime:= now; //Empfangszeit, wenn sData[length(sdata)]=#0 dann sdata:=copy(sdata,1,length(sdata)-1);//String-Format für C-Sprachkompatibilität bSendSeccess:=DataSend(sdata,PortID);//Datenverteiler aufrufen, um Versandmethode zu senden, PortID ist Ziel-Port-IDif (TSCfg.LogOnlyError=false) oder (bSendSeccess=false) theniLogID:=writeLog(dTime, now,sData, PortID, bSendSeccess);//Protokolle gemäß den Protokollverarbeitungsregeln aufzeichnen und Ergebnisse in den Systemkonfigurationsinformationen senden, wenn (TSCfg.Queueing=True) und (bSendSeccess=false) dann PutQueue(dTime, now,sData, PortID, bSendSeccess, iLogID) ; / /Bestimmen Sie das Warteschlangenverarbeitungsende basierend auf der Warteschlangenkonfigurationsdefinition in den oben genannten Daten Die DataArrive-Methode des Dispatchers, bei der die Warteschlangenverarbeitung anhand der Systemkonfigurationsinformationen und des Sendestatus bestimmt wird, kann auch an die obligatorische Warteschlangenverarbeitung angepasst werden. Das Folgende ist die DataSend-Methode von Data Dispatcher, die zum Verteilen und Verarbeiten von Daten gemäß dem Zielporttyp verwendet wird: Funktion TCarrier.DataSend(sData:String;PortID:Integer):boolean;var Obj:TComponent;begin DataSend:= false;Obj:=FindComponent ('Send'+inttostr(PortID)); //Finde das Objekt basierend auf der Port-ID, wenn (obj=nil) oder (obj.Tag =-1) then exit;//Das Objekt existiert nicht oder wurde aufgrund eines Initialisierungsfehlers als ungültig markiert. Tag von 1:DataSend:=PutTCP(TClientSocket(obj),sdata); 3:DataSend:=PutSMTP(TIdSMTP (obj), sdata); 5:DataSend:=PutFTP(TIdFTP(obj),sdata); 7:DataSend:=PutHTTP(TIdHTTP(obj),sdata); 9:DataSend:=PutFile(TFilePort(obj),sdata); 11:DataSend:=PutMSMQ(TMSMQPort (obj),sdata); PutDB(TDBPort(obj),sdata); 15:DataSend:=PutCOM(TCOMPort (obj),sdata); …………… …………… end;end; Es ist erwähnenswert, dass es nur eine Instanz von jedem gibt, wenn kein Objektarray verwendet wird Typ des Ports: Wenn ja, wäre die Verwendung einer Rückruffunktion eine bessere Möglichkeit, die Datenverteilung zu handhaben. Im aktuellen Fall würde dies jedoch dazu führen, dass nicht bekannt ist, welches Mitglied des Objektarrays die Daten verarbeiten soll. Darüber hinaus trennt die aktuelle Verarbeitungsmethode den Transceiver-Kernel und die Transceiver-Shell nicht vollständig, und wir sollten nach einer abstrakteren und unabhängigeren Verarbeitungsmethode suchen. viii. Datenversand Das Folgende ist die Sendefunktion von TCP TCarrier.PutTCP(TCPOBJ:TClientSocket;sdata:string):Boolean;var itime:integer;begin PutTCP:=false; try TCPOBJ.Close; TCPOBJ.Open; gettickcount; //Startzeit wiederholen application.ProcessMessages; bis (TCPOBJ.Active=true) oder (gettickcount-itime>5000); //Aus der Schleife springen, wenn die Verbindung erfolgreich ist oder das 5-Sekunden-Timeout auftritt, wenn TCPOBJ.Active then begin TCPOBJ.Socket.SendText(sdata);//The Rückgabewert ist nur, wenn die Daten erfolgreich gesendet wurden; TCPOBJ.Close; Das Folgende ist die Sendefunktion von COM TCarrier.PutCOM(COMOBJ:TCOMPort;sdata:string):Boolean;var Com:OleVariant;begin PutCOM:=false; try Com:=CreateOleObject(COMOBJ.ComFace);//Erstellen Sie eine vordefinierte Schnittstelle PutCOM:=Com.PutData ( sdata);//Rufen Sie die vordefinierte Methode Com:= Unassigned;exclusiveCom:=Unassigned; Ende; Andere Arten des Port-Sendens sind ähnlich und werden hier nicht wiederholt. Bisher ist die grundlegende Verarbeitung von Quelle und Ziel abgeschlossen. Eine grundlegende Kommunikationsfunktion wurde eingerichtet. Nach freier Abstimmung verschiedener Arten von Quelle und Ziel können völlig unterschiedliche Kommunikationsfunktionen realisiert werden. Durch die Erstellung mehrerer Kanäle können Sie die Kommunikationsverarbeitung für mehrere verschiedene Funktionen zentral implementieren. ix. Warteschlangenverarbeitung: Nachdem die Daten in der oben genannten DataArrive-Methode gesendet wurden, ruft Data Dispatcher die writeLog-Methode für die Datenprotokollierung und die PutQueue-Methode für die Warteschlangenverarbeitung auf. Beide verarbeiten die Dateninformationen entsprechend Systemparameter sind nicht Gegenstand dieses Artikels. Die Wiederholungsverarbeitung der Warteschlange ähnelt dem Prinzip der Verteilung der Verarbeitung nach Porttyp im Timer-Ereignis. Sie basiert auf dem Auslöser des Warteschlangen-Timers, um die gepufferten Daten aus der Datenbank zu lesen und DataSend entsprechend der Ziel-Port-ID erneut aufzurufen Versuchen Sie erneut, die Daten zu senden. Wenn die Übertragung erfolgreich ist, ist die Transaktion dieser Datenübertragung abgeschlossen. Andernfalls wird die Warteschlange erneut eingegeben und auf die nächste Triggerzeit gewartet, bis die Übertragung erfolgreich ist oder die maximale Anzahl von Wiederholungen erreicht ist erreicht ist. drei, Zusammenfassung der Entwicklungserfahrung Da der Schwerpunkt dieses Artikels auf der Erläuterung der Kernideen und Designkonzepte von Transceiver liegt, vereinfacht und schwächt er die Multithreading-Verarbeitung, das Objektpooling und die Transaktionsunterstützung, die Transceiver als Hintergrunddienst betrachten sollte, und ist komplexer und leistungsstarke Quell- und Zielgruppen nnel-Integration, die Fähigkeit zum Senden und Empfangen von Speicherobjekten, Datenströmen, Binärdaten, das Lesen von Systemkonfigurationsinformationen und die Implementierung seiner Kapselungsklassen, die Sicherheit des Systems und der Daten usw. Ich hoffe, dass die Leser einige Einblicke geben können und Verstehen Sie die Designideen von Transceiver und wecken Sie Inspiration bei der tatsächlichen Entwicklungsarbeit und schaffen Sie herausragendere und leistungsfähigere Software. Autor: Firebird [email protected] Verwenden Sie Delphi zum Einrichten von Kommunikations- und Datenaustauschservern – Technische Analyse von Transceivern (Teil 1) Verwenden Sie Delphi zum Einrichten von Kommunikations- und Datenaustauschservern – Technische Analyse von Transceivern (Teil 2) Implementieren Sie Sammlungsklassen über C#. Übersicht über . NET-Sammlungen und verwandte alte technische Dinge: Programmverknüpfungen/Programmlöschungen/selbstlöschende EXE-Dateien alte DIY-Dinge: Erfahrungsnotizen zum Programmieralgorithmus aus der Kindheit