Autor Beitrag
Jojojoxx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 386



BeitragVerfasst: Fr 30.12.05 17:07 
Hallo!

Ich möchte ein Array übertragen mittels der ServerSocket/ClientSocker-Komponente.
meine Code sieht folgendermaßen aus:

Server:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
serversocket1.port:=Port2;
Serversocket1.active:=True;

serversocket1.Socket.ReceiveBuf(Userlist,SizeOf(Userlist));

  for i:=0 to high(Userlist) do
 listbox1.items.add(Userlist[i,1]);


Client:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
    clientsocket1.Port:=Port2;
    clientsocket1.Address:=IPAdresse;
    clientsocket1.active:=true;
    clientsocket1.Socket.SendBuf(Userlist, Sizeof(Userlist));
    clientsocket1.active:=False;


Aber irgendwie bekomme ich im Listbox1-Feld nix angezeigt. Fehlermeldungen erscheinen keine.
Hat da jemand eine Idee??
Danke euch!

mfg

Jojo

Moderiert von user profile iconraziel: Quote- durch Delphi-Tags ersetzt
Moderiert von user profile iconraziel: Topic aus VCL (Visual Component Library) verschoben am Fr 30.12.2005 um 16:21
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 30.12.05 17:26 
Moin!

Zeig mal deine Array-Deklaration.

Ansonsten das Übliche: Es ist nie eine gute Idee, Speicherstücke zu transportieren, ich rate wie immer zu einem Protokoll!

cu
Narses
Muetze1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 346



BeitragVerfasst: Fr 30.12.05 18:00 
Und vor allem: Socket auf True setzen und sofort Daten auslesen wollen? Dir ist schon bewusst, das man das erst machen kann, wenn Daten angekommen sind? Mit anderen Worten: lese Daten im OnClientRead aus und nicht direkt nach dem Active auf True setzen. Die Sockets arbeiten zu deinem Programmablauf asynchron, daher musst du so oder so die Events nutzen und nicht einfach wild irgendwelche Methoden aufrufen.

Dann beachte auch, das das OnClientRead mehrfach aufgerufen werden kann, bis dein komplettes Array empfangen wurde. Daher musst du dir bei jedem OnClientRead erstmal das empfangene in einen Buffer packen der sich so langsam mit jedem Aufruf füllt, bis er das komplett Array enthält. Auch ist daher wichtig zu wissen, wie gross das Array ist, also wieviele Bytes empfangen werden müssen, bevor man das Array auslesen kann. Und genau aus diesen Gründen empfiehlt sich ein Protokoll, wie Narses schon bemerkte.

_________________
49 63 68 68 61 62 65 6B 65 69 6E 65 41 68 6E 75 6E 67 21
Jojojoxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 386



BeitragVerfasst: Fr 30.12.05 19:00 
Hi!

@Muetze1: Die Zeilen
ausblenden Delphi-Quelltext
1:
2:
3:
4:
serversocket1.Socket.ReceiveBuf(Userlist,SizeOf(Userlist));

  for i:=0 to high(Userlist) do
 listbox1.items.add(Userlist[i,1]);

werden im OnClientRead ausgeführt, trotzdem funktioniert es nicht!! :-(


Wie müsste ich denn vorgehen, wenn ich ein Protokoll benutzen wollte??

mfg

Jojo
Muetze1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 346



BeitragVerfasst: Sa 31.12.05 03:59 
1. Wie gross ist UserList?
2. Welchen Typ hat UserList?
3. Wie sendest du Userlist?
4. Warum überprüfst du vor dem ReceiveBuf() nicht überhaupt mal, ob SizeOf(UserList) überhaupt schon im Buffer sind? Siehe dazu ReceiveLength().

_________________
49 63 68 68 61 62 65 6B 65 69 6E 65 41 68 6E 75 6E 67 21
Jojojoxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 386



BeitragVerfasst: Sa 31.12.05 14:34 
Hi!

1. Die Größe von Userlist ist variabel. Zum Testzeitpunkt wird der Wert "4" zurückgegeben (Bytes???, KBytes???).
2. Userlist ist ein Array vom Typ "Array of array[1..2] of String;".
3. Was meinst du mit "Wie sendest du die Userlist?"
4. Muss ich zuerst einen Buffer deklarieren, wohin die Daten kommen, die ich dann anschließend weiterverarbeiten, z.b. auf ne Variable schrieben kann?

mfg

Jojo
Muetze1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 346



BeitragVerfasst: Sa 31.12.05 19:58 
user profile iconJojojoxx hat folgendes geschrieben:
1. Die Größe von Userlist ist variabel. Zum Testzeitpunkt wird der Wert "4" zurückgegeben (Bytes???, KBytes???).


4 Bytes - aus dem einfachen Grund, da es ein dynamisches Array ist und du somit nur ein Adresse hast. Du sendest die ganze Zeit nur die Adresse des Arrays in dem Speicherbereich deiner Anwendung, aber nicht das Array selber.

user profile iconJojojoxx hat folgendes geschrieben:
2. Userlist ist ein Array vom Typ "Array of array[1..2] of String;".


Und daher musst du es alles einzelnd senden. Daher musst du am besten als erstes die Anzahl der Einträge in dem dynamischen Array senden und dann die beiden Strings pro Eintrag. Die Strings an sich solltest du dabei wiederrum mit einer Länge vorher versenden.

user profile iconJojojoxx hat folgendes geschrieben:
3. Was meinst du mit "Wie sendest du die Userlist?"


Weil ich schon ein dynamisches Array vermutet hatte, wollte ich nachfragen ob du nicht schon teilweise Dinge machst, wie ich es in 2. beschrieben habe.

user profile iconJojojoxx hat folgendes geschrieben:
4. Muss ich zuerst einen Buffer deklarieren, wohin die Daten kommen, die ich dann anschließend weiterverarbeiten, z.b. auf ne Variable schrieben kann?


Nein, den Buffer den ich angesprochen hatte, den haben die Socket Komponenten selber bei sich. Ich meinte aber auch, dass du dir einen Speicher anlegen müsstest, weil du kannst das Array ja erst auslesen, wenn alle Daten komplett empfangen wurden.

_________________
49 63 68 68 61 62 65 6B 65 69 6E 65 41 68 6E 75 6E 67 21
Fighter#1
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 787

Win XP, Ubuntu 8.04
Turbo Delphi 2006, Delphi 2005 Pe, Delphi 5 Pe, Netbeans 6.1, Eclipse, Microsoft VisualC#, Dev C++, PHP, HTML, CSS
BeitragVerfasst: So 01.01.06 10:37 
Ich hab das ganze mal mit ner Stringlist probiert.
Geht auch ganz gut.#Vielleicht hilfts dir weiter:

Client Sendet:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var Userlist : TStringList;
begin
Userlist:=TstringList.Create;
Userlist.Add('Zeile1');
Userlist.Add('Zeile2');
ClientSOcket1.Socket.sendText(Userlist.CommaText);



Server empfängt
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var Userlist : TStringList;
begin
Userlist:=TstringList.Create;
Userlist.Commatext:=Socket.ReceiveText;
ShowMessage(Userlist.CommaText);
Memo1.Lines:=Userlist;



Also bei mir hats geklappt

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt
Muetze1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 346



BeitragVerfasst: So 01.01.06 14:22 
1. TStringList und Array sind komplett verschieden
2. Warum nutzt du die CommaText Eigenschaft und nicht einfach nur die Text Eigenschaft der TStrings-Nachfahren?

_________________
49 63 68 68 61 62 65 6B 65 69 6E 65 41 68 6E 75 6E 67 21
Jojojoxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 386



BeitragVerfasst: So 01.01.06 14:49 
Hi!
Danke!! Habs soweit verstandend, aber zwei Fragen hätt ich noch:

Zitat:

Und daher musst du es alles einzelnd senden. Daher musst du am besten als erstes die Anzahl der Einträge in dem dynamischen Array senden und dann die beiden Strings pro Eintrag. Die Strings an sich solltest du dabei wiederrum mit einer Länge vorher versenden.

Was meinst du mit die Strings mit einer Länge versehen?


Nein, den Buffer den ich angesprochen hatte, den haben die Socket Komponenten selber bei sich. Ich meinte aber auch, dass du dir einen Speicher anlegen müsstest, weil du kannst das Array ja erst auslesen, wenn alle Daten komplett empfangen wurden.[/quote]
Wie kann ich mir denn einen Speicher anlegen??

Danke euch!

mfg

Jojo
Fighter#1
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 787

Win XP, Ubuntu 8.04
Turbo Delphi 2006, Delphi 2005 Pe, Delphi 5 Pe, Netbeans 6.1, Eclipse, Microsoft VisualC#, Dev C++, PHP, HTML, CSS
BeitragVerfasst: So 01.01.06 15:03 
user profile iconMuetze1 hat folgendes geschrieben:
1. TStringList und Array sind komplett verschieden
2. Warum nutzt du die CommaText Eigenschaft und nicht einfach nur die Text Eigenschaft der TStrings-Nachfahren?


1. Das kann schon sein, aber man kann die Stringlist ja in Arrays packen.
Ich glaube in diesem Fall währe sogar die Stringlist ausreichend!

2. Ich war nicht sicher ob er mit Text das ganze wieder in einzelne Zeilen packt.
Muetze1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 346



BeitragVerfasst: So 01.01.06 16:07 
user profile iconJojojoxx hat folgendes geschrieben:
user profile iconMuetze1 hat folgendes geschrieben:
Und daher musst du es alles einzelnd senden. Daher musst du am besten als erstes die Anzahl der Einträge in dem dynamischen Array senden und dann die beiden Strings pro Eintrag. Die Strings an sich solltest du dabei wiederrum mit einer Länge vorher versenden.

Was meinst du mit die Strings mit einer Länge versehen?


Da du ja auf der Empfangseite wissen musst wie lang die Zeichenkette ist die du empfangen willst - also wo sie wieder aufhört - wäre es am besten vor jedem String den du sendest die Länge des selbigen zu verschicken. Dazu einfach einen Integer verschicken, der die Länge des Strings beinhaltet. Da SizeOf(String) ja nicht funktioniert - hatten wir oben ja schon.

user profile iconJojojoxx hat folgendes geschrieben:
user profile iconMuetze1 hat folgendes geschrieben:
Nein, den Buffer den ich angesprochen hatte, den haben die Socket Komponenten selber bei sich. Ich meinte aber auch, dass du dir einen Speicher anlegen müsstest, weil du kannst das Array ja erst auslesen, wenn alle Daten komplett empfangen wurden.

Wie kann ich mir denn einen Speicher anlegen??


Nutze einfach einen TMemoryStream - das geht relativ einfach. Einfach im OnClientRead die Daten die neu empfangen wurden von den Sockets lesen und dem MemoryStream hinten anhängen. Danach kannst du ja vorne im MemoryStream auslesen, wie lang die Daten insgesamt sind und vergleichen ob der Memorystream schon alles beinhaltet. Wenn ja, alles auslesen und MemoryStream um die ausgelesenen Daten von vorne an kürzen oder halt warten - beim nächsten OnClientRead prüft er es ja eh wieder neu - vllt. ist es dann ja schon komplett.

Du könntest dir Teile davon bei meinem Chat Beispiel abschauen - aber wie gesagt nur Teile, da mein Chat das alles mit Protokoll und daher komplizierter macht. Aber die Stellen mit dem Memorystream und dem Lesen/Schreiben von Strings sind darin zu finden.

user profile iconFighter#1 hat folgendes geschrieben:
1. Das kann schon sein, aber man kann die Stringlist ja in Arrays packen.
Ich glaube in diesem Fall währe sogar die Stringlist ausreichend!


Aber ein wenn du ein Array Of TStringList hast, dann hast du wiederrum das Problem von dynamischen Arrays. Wenn du dieses Array in den Stream packen willst, dann kannst du es vergessen, da er dann wieder nur die Adresse des dynamischen Arrays sendet. Auch da das Array als Elmente wiederrum nur Instanzenadressen (also Zeiger) beinhaltet, wirst du nicht weiter kommen. Auch das SendText() würde in diesem Falle überhaupt nix bringen, da die Trennung der Array-Element nicht gegeben ist.

_________________
49 63 68 68 61 62 65 6B 65 69 6E 65 41 68 6E 75 6E 67 21
Fighter#1
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 787

Win XP, Ubuntu 8.04
Turbo Delphi 2006, Delphi 2005 Pe, Delphi 5 Pe, Netbeans 6.1, Eclipse, Microsoft VisualC#, Dev C++, PHP, HTML, CSS
BeitragVerfasst: So 01.01.06 19:52 
@Muetze1: Ich meine wenn du die Stringlist empfangen hast kannst du sie in einen Array of
String packen. ( ich probier erst das was ich kann, dann was anderes. )
Jojojoxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 386



BeitragVerfasst: Do 05.01.06 13:40 
Hi!

Ich krieg das senden vom dynamischen Array einfach nicht hin :(
Gibt es evtl. eine andere Möglichkeit, als ein dynamisches Array? Aufgabe ist folgendes:
Es wird eine Liste angelegt, wo jedem User eine IP-Adresse zugeteilt bekommt. Dafür ist mein dynamisches Array dagewesen.
Ist evtl. eine andere Lösung dafür sinnvoller???

mfg

Jojo
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 05.01.06 13:59 
Moin!

Ich wiederhole mich gerne, aber begrenzt: Suche in: Delphi-Forum, Delphi-Library PROTOKOLL

cu
Narses
Jojojoxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 386



BeitragVerfasst: Do 05.01.06 14:47 
Hi!

Sei mir nicht böse, aber ich komm damit nicht ganz klar... :(
Was genau meinst du denn mit Protokoll??
Was ich jetzt dazu gefunden habe ist z.B., dass ich Kommandos vom Server/Client sende/empfange, die der Client/Server dann befolgen kann. Aber ich verstehe nicht, inwiefern mir das beim senden eines dynamischen Arrays helfen kann!

mfg

Jojo
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 05.01.06 14:55 
Moin!

OK, dann versuche ich das mal deutlicher: Du solltest IMHO die Finger davon lassen, ein dyn. Array selbst zu versenden und dich statt dessen besser um ein Kommunikationsprotokoll kümmern, mit dem du steuerst, wie sich Client und Server unterhalten; dann ist es ein leichtes, den Inhalt des dyn. Arrays zu übertragen.

Es geht also erstmal darum, die Art und Weise zu definieren, wie sich Client und Server unterhalten. Das ist schon alles, ein Protokoll.

Wenn du ein Protokoll entwickelt hast (oder auf ein vorhandenes aufsetzen willst; je nach dem), dann erweiterst du dieses um die Möglichkeit, den Inhalt des Arrays transportieren zu können.

cu
Narses

//EDIT: Guckst du hier