Entwickler-Ecke
Internet / Netzwerk - TStringList übers LAN Senden!
pyr0t0n - Di 19.06.07 19:36
Titel: TStringList übers LAN Senden!
Aloa,
ich habe ne kleine Frage. Wie kann ich eine TStringList per Socket Komponenten übertragen? und auf der Anderen Seite wieder in einem TStringList bzw einer ListBox darstellen ?
hat da einer ne idee zu ?
Danke schonmal
Mfg
pyr0
pyr0t0n - Di 19.06.07 19:54
Also erstmal DANKE
aber gibts da auch ne einfachere möglichkeit ohne gleihc ein Protokoll zu entwerfen? also konnte die TStrings nun in einen TStream umwanden und senden geht ja dann mit Socket.SendStream doch der empfang auf der anderen seite macht mir noch probs.
gruß
pyr0
Narses - Di 19.06.07 19:58
Moin!
pyr0t0n hat folgendes geschrieben: |
| Also erstmal DANKE |
Bitte. ;)
pyr0t0n hat folgendes geschrieben: |
| aber gibts da auch ne einfachere möglichkeit ohne gleihc ein Protokoll zu entwerfen? |
IMHO - nein. :|
pyr0t0n hat folgendes geschrieben: |
| also konnte die TStrings nun in einen TStream umwanden und senden geht ja dann mit Socket.SendStream doch der empfang auf der anderen seite macht mir noch probs. |
Genau, deshalb solltest du mal
hier [
http://www.delphi-library.de/topic_Warum+gibt+es+kein+ReceiveStream+bei+den+Sockets_65367.html] und
hier [
http://www.delphi-library.de/topic_Datenpakete+bei+den+SocketKomponenten+auseinanderhalten_56194.html] nachlesen :les: warum das so ist. :D
Eine Alternative wären die
TNBFPA-Komponenten [
http://www.delphi-forum.de/topic_71223.html], damit kannst du dir das ganze Protokoll-Geraffel vom Hals halten und dich auf das Andere konzentrieren. Hier ein Beispiel, wie einfach es damit ginge: ;)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, NarsesBFPA, StdCtrls;
const CMD_ListBox = 1;
type TForm1 = class(TForm) ListBox1: TListBox; ListBox2: TListBox; Button1: TButton; NBFPAClient1: TNBFPAClient; NBFPAServer1: TNBFPAServer; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure NBFPAServer1ClientExecute(Sender: TObject; PA: TProtocolAdapter); procedure FormClose(Sender: TObject; var Action: TCloseAction); private public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); begin NBFPAServer1.Open; Application.ProcessMessages; NBFPAClient1.Connect; end;
procedure TForm1.Button1Click(Sender: TObject); var Cmd: TCmdSeq; begin Cmd := TCmdSeq.Create(CMD_ListBox); Cmd.Add(ListBox1.Items); NBFPAClient1.SendAndFree(Cmd); end;
procedure TForm1.NBFPAServer1ClientExecute(Sender: TObject; PA: TProtocolAdapter); var i: Integer; begin case PA.CurrentToken of CMD_ListBox: begin ListBox2.Clear; for i := 1 to PA.CurrentArgCount-1 do ListBox2.Items.Add(PA.Inbound.Strings[i]); end; end; end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin NBFPAClient1.Disconnect; Application.ProcessMessages; NBFPAServer1.Close; end;
end. |
cu
Narses
pyr0t0n - Di 19.06.07 20:14
Naja vllt sollte ich mein prob doch nochmal weiter erläutern,
also ich habe mehrere Clienten auf denen ich die Windows Prozess liste abrufen kann das geschieht über diese Funktion:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure GetProcessList(const aProcessList: TStrings); var Snap: THandle; ProcessE: TProcessEntry32; begin aProcessList.Clear; Snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); try ProcessE.dwSize := SizeOf(ProcessE); if Process32First(Snap, ProcessE) then Repeat aProcessList.Add(ProcessE.szExeFile); Until not Process32Next(Snap, ProcessE) else RaiseLastOSError; finally CloseHandle(Snap); end; end; |
aufrufen halt über:
Delphi-Quelltext
1:
| GetProcessList(ProzessListe); |
wobei ich ProzessListe vorher schon so deklariert habe
Delphi-Quelltext
1:
| var ProzessListe: TStrings; |
sodale soweit so gut.
Aufdem Server Rechner soll halt diese Liste in einer ListBox wieder angezeigt werden. Und in der übertragung sowie auswertung liegt nun mein problem.
Das Tutorial mit dem Terminator Trennzeichen ist ja nicht schlecht hab mit die Funktion mit dem Senden der UserListe angesehen, aber
ich habe ja bei meiner Tstring überhaupt nicht die erweiterung von .Items geschweige denn .CommaText.
Somit steh ich wieder auf dem schlauch.
Gruß
pyr0
PS: Manch einer mag vllt denken das das hier für einen Trojaner Selbstbau ist dem muss ich aber verneinen das programm soll auf einer LAN zum einsatz kommen und ich möchte cheatern etwas vorbeugen indem ich mir bei Report deren Prozessliste ansehen kann.
Narses - Di 19.06.07 20:17
Moin!
pyr0t0n hat folgendes geschrieben: |
wobei ich ProzessListe vorher schon so deklariert habe
Delphi-Quelltext 1:
| var ProzessListe: TStrings; | |
Laut DOH soll man
TStringsnicht direkt instanziieren! :mahn: :| Also besser
TStringList! :idea:
Ansonsten siehe mein letzter Beitrag. ;)
cu
Narses
pyr0t0n - Di 19.06.07 20:36
Also selbst wenn ich aus TString dann TStringList mache habe ich dieses .Items nicht!?! mache ich denn was falsch ?
Narses - Di 19.06.07 20:40
Moin!
pyr0t0n hat folgendes geschrieben: |
| Also selbst wenn ich aus TString dann TStringList mache habe ich dieses .Items nicht!?! mache ich denn was falsch ? |
Jain ;)
TStringListist ein Nachfahre von
TStrings, genau so wie z.B.
TListBox.Itemsein Nachfahre von
TStringsist. Also hat
TStringListschon die Eigenschaften
.CommaText,
.Text, etc.pp. :idea: Schau doch mal in die DOH... :roll: :les: ;)
Auf das TNBFPA-Beispiel oben bezogen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure TForm1.Button1Click(Sender: TObject); var SL: TStringList; Cmd: TCmdSeq; begin SL := TStringList.Create; try SL.Add('Test1'); SL.Add('Test2'); Cmd := TCmdSeq.Create(CMD_ListBox); Cmd.Add(SL); NBFPAClient1.SendAndFree(Cmd); finally SL.Free; end; end; |
cu
Narses
pyr0t0n - Di 19.06.07 20:51
also die funktion sieht bei mir nun so aus
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| GetProcessList(ProzessListe); try Cmd := TCmdSeq.Create(CMD_ListBox); Cmd.Add(ProzessListe); NBFPAClient1.SendAndFree(Cmd); finally ProzessListe.Free; end; end; |
doch sobald die im client aufgerufen wird bekomme ich
Access violation at address 00458A78 in module 'Client.exe' Read of address 00000000.
Narses - Di 19.06.07 20:55
Moin!
pyr0t0n hat folgendes geschrieben: |
also die funktion sieht bei mir nun so aus
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| GetProcessList(ProzessListe); try Cmd := TCmdSeq.Create(CMD_ListBox); Cmd.Add(ProzessListe); NBFPAClient1.SendAndFree(Cmd); finally ProzessListe.Free; end; end; |
doch sobald die im client aufgerufen wird bekomme ich
| Debugger hat folgendes geschrieben: | | Access violation at address 00458A78 in module 'Client.exe' Read of address 00000000. |
|
Das darfst du natürlich nur dann tun, wenn deine Prozessliste eine lokale Variable ist; wenn die Liste global ist, dann gibst du sie ja entweder zu früh bzw. mehrfach frei :shock: und das gibt natürlich was auf die Finger. :P
Aber mal so am Rande: du meinst nicht, dass ein oder zwei OOP-Tutorials dir gut tun würden... :? :?:
cu
Narses
pyr0t0n - Di 19.06.07 20:57
| Zitat: |
Aber mal so am Rande: du meinst nicht, dass ein oder zwei OOP-Tutorials dir gut tun würden... :? :?:
|
joa bestimmt aber mache delphi eigentlich nur wenn ich schnell was brauche lerne atm c++ ^^
EDIT:
Also habe das Free rasgenommen fehler bleibt allerdings.
Narses - Di 19.06.07 21:05
Moin!
pyr0t0n hat folgendes geschrieben: |
| Also habe das Free rasgenommen fehler bleibt allerdings. |
Mehr Code, bitte. :|
cu
Narses
pyr0t0n - Di 19.06.07 21:12
kk kommt...
Also nochmal die Funktion GetProcessList
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure GetProcessList(const aProcessList: TStringList); var Snap: THandle; ProcessE: TProcessEntry32; begin aProcessList.Clear; Snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); try ProcessE.dwSize := SizeOf(ProcessE); if Process32First(Snap, ProcessE) then Repeat aProcessList.Add(ProcessE.szExeFile); Until not Process32Next(Snap, ProcessE) else RaiseLastOSError; finally CloseHandle(Snap); end; end; |
Dann nochmal der Teil der mir die Liste senden soll, es muss an einem der 2 Sachen liegen, weil der fehler auftritt sobald ich den Button zum senden drücke.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); var antwort : STRING; var Cmd: TCmdSeq; begin antwort := Socket.ReceiveText;
[...]
if antwort = 'PROZLIST' then begin GetProcessList(ProzessListe); try Cmd := TCmdSeq.Create(CMD_ListBox); Cmd.Add(ProzessListe); NBFPAClient1.SendAndFree(Cmd); finally; end; end; |
hoffe des reicht dir weil viel mehr hab ich gar nicht. und auhc nix was irgendein Free hat ^^
Narses - Di 19.06.07 22:07
Moin!
pyr0t0n hat folgendes geschrieben: |
Dann nochmal der Teil der mir die Liste senden soll, es muss an einem der 2 Sachen liegen, weil der fehler auftritt sobald ich den Button zum senden drücke.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); var antwort : STRING; var Cmd: TCmdSeq; begin antwort := Socket.ReceiveText;
[...]
if antwort = 'PROZLIST' then begin GetProcessList(ProzessListe); try Cmd := TCmdSeq.Create(CMD_ListBox); Cmd.Add(ProzessListe); NBFPAClient1.SendAndFree(Cmd); finally; end; end; | |
:shock: Ähm, das sieht so aus, als hättest du da die Komponenten "vermischt"?! :?!?: Also, du darfst NUR die TNBFPA-Kompos ODER die Sockets direkt nehmen, nicht beides durcheinanderbringen! :mahn:
cu
Narses
pyr0t0n - Di 19.06.07 22:12
hm.. doch habs hinbekommen
und zwar hab ich einfach beim Clienten der die ProzessListe senden soll eine ListBox gemacht welche halt unsichtbar ist, dort hatte ich dannauch die funktion Items und komischerweise gehts nun auch..
trotzdem nochmal vielen dank.
aber eine frage hab ich noch...
wie kann ich mit deinen kompos normalen text senden und diesen auswerten ala
wenn gesendeter text = blubb mache das und das
über normale sockets ja
socket.sendtext(STRING) und Socket.ReceiveText
aber wie bei deinen ?
Narses - Di 19.06.07 22:29
Moin!
pyr0t0n hat folgendes geschrieben: |
| und zwar hab ich einfach beim Clienten der die ProzessListe senden soll eine ListBox gemacht welche halt unsichtbar ist, dort hatte ich dannauch die funktion Items und komischerweise gehts nun auch. |
:?!?: ich fürchte, du hast keine Ahnung, was du da machst... :? oder? 8)
pyr0t0n hat folgendes geschrieben: |
| trotzdem nochmal vielen dank. |
Bitte bitte, aber lies dir einfach mal die Protokoll-Tuts durch, ja? :|
pyr0t0n hat folgendes geschrieben: |
aber eine frage hab ich noch...
wie kann ich mit deinen kompos normalen text senden und diesen auswerten ala |
Das läuft bei den TNBFPA-Kompos nicht über Text, sondern über die Kommando-Token (diese
const CMD_ListBox = 1; Geschichte), dafür brauchst du keinen Text. :idea: Bitte Details im
BinProto-Tut [
http://www.delphi-library.de/topic_66706.html] nachlesen. :les:
pyr0t0n hat folgendes geschrieben: |
wenn gesendeter text = blubb mache das und das
über normale sockets ja
socket.sendtext(STRING) und Socket.ReceiveText |
So wie du das ansetzt, ist das eh "falsch", weil du von den Ereignissen nicht auf Datenpaketgrenzen schließen kannst/darfst, das klappt immer nur "zufällig", Details
hier [
http://www.delphi-library.de/topic_56194.html]. Weiterhin bekommst du Probleme, wenn die Datenrate so hoch wird, dass der WSA-Puffer voll läuft, dann liest du mit einem
Socket.ReceiveText nämlich immer nur 8kb, und nicht alles, was bisher eingetroffen ist! :mahn: Insgesamt also: besser Finger von lassen und ein Protokoll nehmen (was mit den TBNFPA-Kompos ja nun wirklich ein Kinderspiel ist, einfach für die Befehle Konstanten definieren und die Parameter an die Sequenz hängen, fertig. Den TClientSocket und den TServerSocket brauchst du dann gar nicht mehr im Projekt. :D)
cu
Narses
pyr0t0n - Mi 20.06.07 18:08
ok Narses eine letzte frage hab ihc aber noch in deinem Code / PDF sendet der Server nur an alle Clienten, was ist wenn ich ein bestimmtes Commando nur an EINEN clienten senden will den ich vorher auf ner ListBox auswähle? also das mit der Listbox krieg ich hin aber das senden an sich an nur einen Clienten.
Narses - Mi 20.06.07 18:20
Moin!
pyr0t0n hat folgendes geschrieben: |
| in deinem Code / PDF sendet der Server nur an alle Clienten, |
Das stimmt nicht ganz ;) hier wird nur an einen was gesendet (den "Neuen"; Auszug aus dem Demo-Code):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TServerMain.NBFPAServer1ClientConnect(Sender: TObject; PA: TProtocolAdapter); var Cmd: TCmdSeq; i: Integer; begin for i := 0 to NBFPAServer1.Connections.Count-1 do if (NBFPAServer1.ConnectionByIndex[i] <> PA) then begin Cmd := TCmdSeq.Create(CMD_USERDATA); Cmd.Add(NBFPAServer1.ConnectionByIndex[i].SessionID); Cmd.Add(NBFPAServer1.ConnectionByIndex[i].SessionName); PA.Outbound.AddCmdAndFree(Cmd); end; end; |
pyr0t0n hat folgendes geschrieben: |
| was ist wenn ich ein bestimmtes Commando nur an EINEN clienten senden will den ich vorher auf ner ListBox auswähle? |
Konkret auf deinen Fall angepasst:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| var Cmd: TCmdSeq; begin Cmd := TCmdSeq.Create(... blah; NBFPAServer1.ConnectionsByIndex[i].Outbound.AddCmdAndFree(Cmd); NBFPAServer1.ConnectionsByIndex[i].Send; |
Damit wird das Kommando an die
i-te Verbindung gesendet. :idea: ;)
cu
Narses
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!