Entwickler-Ecke
Internet / Netzwerk - ServerSocket.Socket.Connections[i].Close;
Pf@nne - Fr 11.02.11 21:47
Titel: ServerSocket.Socket.Connections[i].Close;
Hallo,
mit:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure Tfrm_Server.ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin mem_EventLog.Lines.Add('ClientConnect Handle/IP: ' + IntToStr(Socket.SocketHandle) + ' / ' + Socket.RemoteAddress); Socket.SendText('Hallo'); lbl_ServerIP.Caption := 'IP: ' + socket.LocalAddress; lb_Clients.Items.add(IntToStr(Socket.SocketHandle) + #9 + Socket.RemoteAddress); end; |
füge ich jeden neuen Client der"ListBox_Clients" hinzu.
mit:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure Tfrm_Server.bu_CloseSelectedClick(Sender: TObject); var i: integer; begin while not (lb_Clients.SelCount = 0) do begin for i := 0 to lb_Clients.Count -1 do begin if lb_Clients.Selected[i] then begin ServerSocket.Socket.Connections[i].Close; break; end; end; end; end; |
möchte ich die in der Liste selektierten Clients (auch Multiselekt) schließen.
Leider geht das ganze nur wenn 1 Client selektiert ist.
Bei mehreren geht es nicht mehr.
Ich habe schon bemerkt, dass unmittelbar nach:
ServerSocket.Socket.Connections[i].Close;
sich die Anzahl der serversocket.Socket.ActiveConnections nicht verringert.
Was mache ich verkehrt?
Danke......
Pf@nne - Sa 12.02.11 14:29
gute Idee,
werd ich mich gleich mal ransetzen.... danke :D
ein weiteres Problem:
Delphi-Quelltext
1: 2: 3:
| ServerSocket.Open; lbl_ServerStatus.Caption := 'ONLINE'; lbl_ServerIP.Caption:= 'IP: ' + ServerSocket.Socket.LocalAddress; |
socket.LocalAddress bringt mir 0.0.0.0 erst wenn sich ein Client vernuden hat
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure Tfrm_Server.ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin mem_EventLog.Lines.Add('ClientConnect Handle/IP: ' + IntToStr(Socket.SocketHandle) + ' / ' + Socket.RemoteAddress); Socket.SendText('Hallo'); lbl_ServerIP.Caption := 'IP: ' + socket.LocalAddress; noch änder! end; |
Liefert socket.LocalAddress meine eigene IP, hängt das damit zusammen, dass oben (ServerSocket.Socket.LocalAddress) noch gar kein Socket aktiv ist?
Wie würde man die eigene IP abfragen auch ohne das der Server open ist?
Wie bekomme ich von einem aktiven Socket die MAC herraus?
Wie bekomme ich meine eigene MAC hehrraus?
Fragen über Fragen....
Werd mich auch noch mal ans Tutorial setzen.....
Erst mal Danke.....
---
Moderiert von
Narses: Beiträge zusammengefasst---
Delphi-Quelltext
1: 2: 3: 4:
| procedure Tfrm_Server.ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin lb_Clients.Items.AddObject(IntToStr(Socket.SocketHandle) + #9 + Socket.RemoteAddress , Socket); end; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| procedure Tfrm_Server.bu_CloseSelectedClick(Sender: TObject); var i: integer; SelectedSocket : TCustomWinSocket; begin for i := lb_Clients.Count -1 downto 0 do begin if lb_Clients.Selected[i] then begin SelectedSocket := TCustomWinSocket(lb_Clients.Items.Objects[i]); SelectedSocket.Close; end; end; end; |
läuft wie Teufel..... Danke
Pf@nne - Sa 12.02.11 20:18
Der Delphi-Server ist die Zentrale für meine Haussteuerung.
Die einzelnen 8-Kanal-Dimmerpacks und die Input-Packs kann ich nur anhand der MAC unterscheiden.
Na ja, genau genommen wird diese ja schon vom DHCP-Server abgefragt und die IP festgelegt,
also langt im Grunde die IP.
Der Vollständigkeit halber wäre es zum Testen von interesse.
Danke für die links, werd ich gleich mal durchackern..... :D
Pf@nne
Pf@nne - Sa 26.02.11 16:55
| Zitat: |
besser die Socket-Objekt-Referenz nehmen, dann kannst du direkt damit arbeiten. :idea: Das Connections-Array des ServerSockets solltest du besser komplett ignorieren. :nixweiss:
Hier ist auch noch mal ein Tutorial dazu. ;) |
prima Tip :dance: Danke....
Ich habe mich dran gehalten und die nächste Baustelle aufgemacht.
Ich möchte ein eigenes Object in meine ListBox übergeben, hierzu möchte ich ein TCustomWinSocket um meine Infos "aufbohren".
Delphi-Quelltext
1: 2: 3: 4:
| TClientSocket = class (TCustomWinSocket) ModulAdress: integer; ListIndex: integer; end; |
ist das richtig so?
Dann möchte ich in
Delphi-Quelltext
1: 2: 3: 4:
| procedure Tfrm_Server.ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); var ConnectString: String; NewClient: TClientSocket; begin |
mein Object füllen (NewClient = Socket) und einer weiteren procedure übergeben die das Object vervollständigt und in der Listbox ablegt.
Wie initialisiere ich das Object, kann man das gleich mit dem Socket verbinden?
Delphi-Quelltext
1:
| NewClient.?? := TCustomWinSocket.Create(Socket.SocketHandle)?? |
Ich weiß zwar was ich will, bei der Umsetzung schwächel ich aber :?!?:
Pf@nne - Sa 26.02.11 17:53
| Zitat: |
| Wie initialisiere ich das Object, kann man das gleich mit dem Socket verbinden? |
Ja, natürlich !
Delphi-Quelltext
1:
| NewClient := TClientSocket(Socket); |
:autsch:
Der Rest geht auch
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| procedure Tfrm_Server.ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); var ConnectString: String; NewClient: TClientSocket; begin NewClient := TClientSocket(Socket); ConnectClient(NewClient); |
Delphi-Quelltext
1: 2: 3: 4:
| procedure Tfrm_Server.ConnectClient(NewClient: TClientSocket); begin showmessage(NewClient.LocalAddress); end; |
Was mit richtig lesen und hinsehen so alles geht, erstaunlich.....
Pf@nne - Sa 26.02.11 19:01
Jetzt bekomme ich einen Pointer Fehler beim Schleißen der selektierten Sockets!
Ich hole aus dem selektierten Item meiner ListBox das Objekt herraus (jetzt ein TClientSocket siehe oben)
und dann versuche ich es zu schließen.
hm..... was hat sich geändert?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure Tfrm_Server.bu_CloseSelectedClick(Sender: TObject); var i: integer; SelectedSocket : TClientSocket;
begin for i := lb_Clients.Count -1 downto 0 do begin if lb_Clients.Selected[i] then begin SelectedSocket := TClientSocket(lb_Clients.Items.Objects[i]); SelectedSocket.Close; end; end; end; |
Narses - So 27.02.11 00:09
Moin!
Pf@nne hat folgendes geschrieben : |
Ich möchte ein eigenes Object in meine ListBox übergeben, hierzu möchte ich ein TCustomWinSocket um meine Infos "aufbohren".
Delphi-Quelltext 1: 2: 3: 4:
| TClientSocket = class (TCustomWinSocket) ModulAdress: integer; ListIndex: integer; end; |
ist das richtig so? |
Nein, andersrum wird ein Schuh draus: definiere dein eigenes Objekt, wobei der Socket eine Eigenschaft davon ist. Und das packst du dann in die Listbox. :idea: ;)
cu
Narses
Pf@nne - So 27.02.11 13:22
Immer wieder erstaunlich
kaum macht man es richtig, schon klappt es!
:dance: :dance2:
---
Moderiert von
Narses: Beiträge zusammengefasst---
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure Tfrm_Server.bu_CloseSelectedClick(Sender: TObject); var i: integer; SelectedSocket : TClientSocket;
begin for i := lb_Clients.Count -1 downto 0 do begin if lb_Clients.Selected[i] then begin SelectedSocket := TClientSocket.Create; SelectedSocket := TClientSocket(lb_Clients.Items.Objects[i]); SelectedSocket.ClientSocket.Close; SelectedSocket.Destroy; end; end; end; |
Ist destroy richtig oder lieber free?
Was passiert mit dem Object in meiner ListBox wen das ListBox.Item gelöscht wird?
Muss das Object noch gelöscht werden?
Danke....
Narses - So 27.02.11 13:57
Moin!
Mal zwei "verwaltungstechnische Sachen" vorab: Bitte für "neue" Fragen auch einen neuen Thread aufmachen. Es hat sich gezeigt, dass mehrere (thematisch unzusammenhängende) Fragen in einem Thread früher oder später zu Chaos führen. :idea: (ja, hier trifft das noch nicht zu, würe bei der aktuellen Fragen schon genug Zusammenhang sehen - aber nur mal rein vorsorglich ;)).
Weiterhin solltest du nicht für jedes Info-Schnippselchen einen neuen Beitrag erstellen, sondern besser deinen letzen Beitrag editieren (wie es die Regeln vorsehen). Danke. :)
Pf@nne hat folgendes geschrieben : |
| Ist destroy richtig oder lieber free? |
Generell ist .Free die "richtige" Wahl.
Allerdings sehe ich da noch gravierende Fehler in deinem Code:
Pf@nne hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure Tfrm_Server.bu_CloseSelectedClick(Sender: TObject); var i: integer; SelectedSocket : TClientSocket; begin for i := lb_Clients.Count -1 downto 0 do begin if lb_Clients.Selected[i] then begin SelectedSocket := TClientSocket.Create; SelectedSocket := TClientSocket(lb_Clients.Items.Objects[i]); SelectedSocket.ClientSocket.Close; SelectedSocket.Destroy; end; end; end; | |
Du hast doch nur eine Referenz in deiner Listbox und bist gar nicht Eigentümer des Objekts, noch dazu
legst du ein weiteres Objekt an (und auch noch dazu die GUI-Kompo!), was du dann nicht mehr frei gibst!? :shock:
Du solltest das besser so machen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| var i: Integer; begin for i := lb_Clients.Count-1 downto 0 do if lb_Clients.Selected[i] then TCustomWinSocket(lb_Clients.Items.Objects[i]).Close; |
Unterstellt, dass du "nur" eine Socket-Referenz aus den Ereignismethoden der Socket-Komponenten arbeitest. Du wolltest doch ein eigenes Objekt verwenden: da sieht das natürlich etwas anders aus. :nixweiss:
Pf@nne hat folgendes geschrieben : |
Was passiert mit dem Object in meiner ListBox wen das ListBox.Item gelöscht wird?
Muss das Object noch gelöscht werden? |
Wenn es nur eine Referenz ist, dann braucht es dich nicht zu kümmern, was damit passiert, du bist ja nicht Eigentümer. Wenn es "dein" Objekt ist, wo die Socket-Referenz nur eine Eigenschaft ist, dann musst du dich natürlich auch um die Speicherverwaltung kümmern. :idea:
cu
Narses
Pf@nne - So 27.02.11 15:05
@Narses
Danke für die "verwaltungstechnischen" Hinweise, ich werde mich bemühen die Hinweise zu berücksichtigen. :)
Ich bin ein Object-Anfänger, irgendwie tu ich mich damit schwer....
Ich habe mir ein eigenes Objekt gemacht, richtig?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| type TTCP_Client = class (TObject) Socket: TCustomWinSocket; Connected: boolean; LastPing: TDateTime; ModulAdress: integer; IP: String; Typ: Integer; HW: Integer; end; |
dieses Object benutze ich um ein TCustomWinSocket darin zu verstauen.
Dazu muss ich doch erst mal mein object erzeugen, richtig?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure Tfrm_Server.ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); var NewClient: TTCP_Client; begin NewClient := TTCP_Client.Create; NewClient.Socket := TCustomWinSocket(Socket); ConnectClient(NewClient); end; |
Um es dann in meiner Liste für den späteren Gebrauch zu parken.
Delphi-Quelltext
1: 2: 3: 4:
| procedure Tfrm_Server.ConnectClient(NewClient: TTCP_Client); nur socket übergeben!! begin lb_Clients.Items.AddObject('???' + #9 + NewClient.Socket.RemoteAddress , NewClient); end; |
Bei Bedarf durchsuche ich meine Liste, entnehme das Object und schließe den Zeiger auf den Socket
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure Tfrm_Server.bu_CloseSelectedClick(Sender: TObject); var i: integer;
begin for i := lb_Clients.Count -1 downto 0 do begin if lb_Clients.Selected[i] then begin TTCP_Client(lb_Clients.Items.Objects[i]).Socket.Close; end; end; end; |
Aber wo setze ich mein Object wieder frei?
Ich finde das ganz schön komplex, ich hab jetzt einen Knoten im Hirn. :nut:
Narses - So 27.02.11 15:55
Moin!
Pf@nne hat folgendes geschrieben : |
Ich habe mir ein eigenes Objekt gemacht, richtig?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| type TTCP_Client = class (TObject) Socket: TCustomWinSocket; LastPing: TDateTime; ModulAdress: integer; Typ: Integer; HW: Integer; end; | |
Die beiden auskommentierten Eigenschaften hätte ich weggelassen, sind redundant.
Pf@nne hat folgendes geschrieben : |
| dieses Object benutze ich um ein TCustomWinSocket darin zu verstauen. |
:zustimm:
Pf@nne hat folgendes geschrieben : |
Dazu muss ich doch erst mal mein object erzeugen, richtig?
[...]
Um es dann in meiner Liste für den späteren Gebrauch zu parken. |
Ich hätte das gleich zusammengefasst, die zusätzliche Methode bringt hier nix. :nixweiss:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure Tfrm_Server.ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); var NewClient: TTCP_Client; begin NewClient := TTCP_Client.Create; NewClient.Socket := TCustomWinSocket(Socket); lb_Clients.Items.AddObject('???' + #9 + NewClient.Socket.RemoteAddress , NewClient); end; |
Pf@nne hat folgendes geschrieben : |
Bei Bedarf durchsuche ich meine Liste, entnehme das Object und schließe den Zeiger auf den Socket
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| procedure Tfrm_Server.bu_CloseSelectedClick(Sender: TObject); var i: Integer; begin for i := lb_Clients.Count -1 downto 0 do if lb_Clients.Selected[i] then TTCP_Client(lb_Clients.Items.Objects[i]).Socket.Close; end; |
Aber wo setze ich mein Object wieder frei? |
Wenn du die Listbox wieder leerst oder ein Item entfernst. ;) Das passiert hier ja nicht, in dem Code werden keine Items entsorgt. :nixweiss:
Es ist aber generell keine gute Idee, die GUI-Kompo für die Datenhaltung zu missbrauchen. Vielleicht solltest du deine Client-Objekte in einer TObjectList speichern (dazu dann vielleicht noch eine Eigenschaft .Caption einführen) und dann nur mit Referenzen in der Listbox arbeiten. Wenn du die TObjectList leerst, werden auch die Objekte freigegeben, ist ObjectList ist ja dann der Eigentümer. :idea:
cu
Narses
Pf@nne - So 27.02.11 16:34
Mohltied,
an dem Punkt bin ich auch gerade, da ich nicht nur einen Client habe, werde ich eine ClientList benutzen.
Delphi-Quelltext
1:
| var ClientList: TList; |
Ich habe das so verstanden:
Beim erzeugen meines Forms erzeuge ich eine neue TList, meine Liste, meine Verantwortung.
Delphi-Quelltext
1: 2: 3:
| procedure Tfrm_Server.FormCreate(Sender: TObject); begin ClientList := TList.Create; |
Bei Bedarf lege ich einen Zeiger auf einen TTCP_Client in der Liste ab, nicht mein Object, regelt die Liste
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure Tfrm_Server.ConnectClient(Socket: TCustomWinSocket); var Index: integer; begin Index := ClientList.Add(TTCP_Client.Create); with TTCP_Client(ClientList.Items[Index]) do begin Socket := Socket; Connected := false; ModulAdress := 0; IP := Socket.RemoteAddress; Typ := 0; HW := 0;
lb_Clients.Items.AddObject('???' + #9 + IP , TTCP_Client(ClientList.Items[Index])); Socket.SendText('‡000001FFFF'); end; |
soweit zu "meiner" Theorie..... fehlt nur noch die Praxis....
Beim Ablegen in der ListBox haperts... warscheinlich schon vorher.....
Doppelte Listen habe ich jetz auch noch (TList, TListBox)....
EDIT
Habe eben noch mal getetet, generel geht es, es liegt an der with-schleife.....
Narses - So 27.02.11 17:07
Moin!
Pf@nne hat folgendes geschrieben : |
| an dem Punkt bin ich auch gerade, da ich nicht nur einen Client habe, werde ich eine ClientList benutzen. |
Ich rate dir zu einer TObjectList, damit hast du die Speicherverwaltung nicht am Hals:
Delphi-Quelltext
1: 2:
| public ClientList: TObjectList; |
Pf@nne hat folgendes geschrieben : |
Ich habe das so verstanden:
[...]
Bei Bedarf lege ich einen Zeiger auf einen TTCP_Client in der Liste ab, nicht mein Object, regelt die Liste |
Nope, das wäre bei der TObjectList so, die TList ist keine Container-Klasse, da darfst du die Speicherverwaltung selbst machen!
Etwa so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure Tfrm_Server.ConnectClient(Socket: TCustomWinSocket); var NewClient: TTCP_Client; begin NewClient := TTCP_Client.Create; NewClient.Socket := Socket; ClientList.Add(NewClient); lb_Clients.Items.AddObject('???' + #9 + IP , NewClient); Socket.SendText('‡000001FFFF'); end; |
Objekte aus der ClientList müssten dann beim Disconnect-Ereignis wieder entfernt werden. :idea:
Pf@nne hat folgendes geschrieben : |
| Doppelte Listen habe ich jetz auch noch (TList, TListBox).... |
So kannst du das nicht sehen, du hast jetzt eine Liste zur Datenhaltung, die auch als Eigentümer funktioniert (und damit die Speicherverwaltung kapselt) und eine GUI-Kompo, die eine Referenz auf das Objekt in der Anzeige bereit stellt. ;)
cu
Narses
Pf@nne - So 27.02.11 17:43
Delphi-Quelltext
1:
| ClientList.Add(NewClient); |
Das heißt die Liste kümmert sich auch um das Schließen, des eben neu erzeugten Objects?
Was passiert dann hier?
Delphi-Quelltext
1:
| ClientList.Add(TTCP_Client.Create); |
Funktioniert irgendwie auch, ist das denn völlig falsch, abgesehen davon das der TCP_Client dann noch leer ist.
zuweisen wollte ich dann mit
Delphi-Quelltext
1: 2: 3:
| Index := ClientList.Add(TTCP_Client.Create); with TTCP_Client(ClientList.Items[Index])do |
das geht dann aber nicht mehr... :roll:
Warscheinlich weil meine Zuweisung Müll ist :mrgreen:
Narses - So 27.02.11 18:01
Moin!
Pf@nne hat folgendes geschrieben : |
| ClientList.Add(NewClient); Das heißt die Liste kümmert sich auch um das Schließen, des eben neu erzeugten Objects? |
Schließen? :gruebel: Wenn du damit "Freigeben" meinst, dann ja. :nixweiss: Mit dem Socket, der da als Referenz drin ist, hat das erstmal nix zu tun. :idea:
Pf@nne hat folgendes geschrieben : |
Was passiert dann hier?
Delphi-Quelltext 1:
| ClientList.Add(TTCP_Client.Create); | Funktioniert irgendwie auch, ist das denn völlig falsch, abgesehen davon das der TCP_Client dann noch leer ist. |
Klar funktioniert das auch, du hast aber eben keine Referenz auf das neue Objekt zur Hand, ist also nur unpraktisch. ;)
Pf@nne hat folgendes geschrieben : |
zuweisen wollte ich dann mit
Delphi-Quelltext 1: 2: 3:
| Index := ClientList.Add(TTCP_Client.Create); with TTCP_Client(ClientList.Items[Index])do | |
Lass dir raten: verzichte auf with-Konstrukte, das sind Zeitbomben. Ja, machen den Code kleiner, aber werden dir wegen unklarem Fokus irgendwann wieder um die Ohren fliegen... :nixweiss:
Pf@nne hat folgendes geschrieben : |
das geht dann aber nicht mehr... :roll:
Warscheinlich weil meine Zuweisung Müll ist :mrgreen: |
;)
cu
Narses
Pf@nne - So 27.02.11 19:53
Hi Narses,
vielen Dank für den Einzelunterricht..... :wink2:
läuft alles wie die Feuerwehr....
Nochmals Danke....
Narses - So 27.02.11 21:27
Moin!
Markierst du den Thread noch entsprechend, wenn dein Problem gelöst ist? Danke. ;)
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!