| Autor |
Beitrag |
BAERnado
Hält's aus hier
Beiträge: 11
|
Verfasst: Sa 04.11.06 19:18
Hi,
ich erstelle in meinem Programm variabel ein ClientSocket, doch möchte ich ihm einen String mit auf den Weg geben, den er dann OnConnect sendet. Da ich aber keine Idee hatte, wie ich dem Objekt den String mit auf den Weg geben sollte, habe ich versucht, eine Ableitung von TClientSocket zu machen und dieser einen String mit auf den Weg zu geben.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| unit PSockets;
interface
uses ScktComp;
type TDCClientSocket = class(TClientSocket) private SAddInfo: String; public property AddInfo: String read SAddInfo Write SAddInfo; end;
implementation
end. |
Wenn der String dann gesendet worden ist, wird der Socket automatisch vom Server getrennt, was auch beabsichtigt ist.
Nun muss das Objekt ja nur noch wieder freigegeben werden.
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TfrmMain.sckDCDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin (Sender as TDCClientSocket).Free; end; |
Leider bekomme ich immer wieder folgenden Fehler:
"Windows-Socket-Fehler: Ein Vorgang bezog sich auf ein Objekt, das kein Socket ist (10038), auf API 'closesocket'"
Der Fehler tritt genau beim Aufruf von Free auf. Ich hab mir auch schon die Prozeduren von TClientSocket angeschaut, um zu finden, wo er stolpert, aber ich finde es nicht.
Hat jemand ne Ahnung, wie ich es entweder besser lösen kann, oder den Fehler umgehen kann? Ich will das Objekt ja auch nicht irgendwo im nirgendwo rumschweben lassen.
Vielen Dank
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Sa 04.11.06 20:14
Moin!
Warum legst du nicht einen statischen ClientSocket an und recyclest diesen für die Kommunikation?!
Was du da konzeptionell tust, ist mindestens bedenklich, wenn nicht sogar schlicht falsch (damit meine ich, einem Objekt einen String anzuflanschen, diesen durch das Erzeugen zum Senden bringen und in einem Ereignis der Komponente(!) diese freigeben  ).
Wenn es denn tatsächlich einen Grund geben sollte, das so zu machen, wie du das angesetzt hast, dann kannst du auf keinen Fall in einem Ereignis einer Komponente diese freigeben, das knallt garantiert immer!  Eine Möglichkeit, dieses "Problem" zu "umgehen", könnte so aussehen: du definierst eine eigene Fensternachricht, in dessen Handler du den ClientSocket freigibst. Diese Nachricht sendest du dir dann im OnDisconnect selbst.
Ich möchte aber wirklich nochmal betonen, dass das, was du da vorhast, so sicherlich nicht gut gelöst ist.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
BAERnado 
Hält's aus hier
Beiträge: 11
|
Verfasst: Sa 04.11.06 20:21
Ich will kein statisches Socket verwenden, weil das Event evtl. erneut ausgelöst wird, noch bevor das erste abgearbeitet ist (z.B. die Verbindung hängt etwas). Die Funktion ist außerdem nur dem onDisconnect-Handler zugewiesen und sollte von daher kein Problem bereiten. Ich meine, mich dran erinnern zu können, dass ich sowas früher schon mal mit einem reinen TClientSocket gemacht habe. Was in meinen Augen auch sinnvoll ist, da ich sonst den Bezug zum Objekt verlieren könnte, da es ja zur Laufzeit erst in einer Funktion erstellt wird und von daher nicht von anderen Funktionen und Prozeduren angesprochen werden kann. Dies würde also verhindern, die Abarbeitung mittels einer Nachricht zu machen.
(Ich wünschte, hier wäre Delphi mal wie VB, wo die Eigenschaft Tag kein Integer, sondern ein String ist  )
Also prinzipiell die variable Instanz beruht darauf, dass ein zweites Objekt erstellt werden könnte, während das erste noch am arbeiten ist.
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Sa 04.11.06 20:32
Moin!
Ich bin nicht dazu berufen, deine Auswahl von Programmieransätzen zu beurteilen. Wenn du das, was du da machst, unbedingt so machen willst, bitte.
Fakt: Du kannst nicht in einem Ereignis einer Socket-Komponente diese selbst freigeben, das wird immer zu einem Fehler führen. Ob dir das passt oder nicht, wird den ClientSocket vermutlich nicht interessieren.
Falls du doch noch Interesse an einer Diskussion für einen alternativen Lösungsansatz haben solltest, bin ich gerne für Vorschläge zu haben.  Dein aktuelles Vorhaben macht keinen Sinn, also erübrigt sich für mich Weiteres dazu.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
BAERnado 
Hält's aus hier
Beiträge: 11
|
Verfasst: Sa 04.11.06 20:44
Sicher würd ich das gern fixen, aber vorher versuch ich das mal, das mit einem stinknormalen TClientSocket in einem Testprojekt hinzubekommen
ok, du hast vollkommen Recht, ich kann ihn leider nicht so killen.
Das heißt, ich müsste evtl über einen Thread gehen, der wartet, bis die Socketverbindung geschlossen ist, damit eine unabhängige Prozedur das Objekt befreien kann?
|
|
BAERnado 
Hält's aus hier
Beiträge: 11
|
Verfasst: Sa 04.11.06 22:00
Ok, Problem gelöst.
Habs über nen Thread laufen lassen, der dann in einer While-Schleife gecheckt hat, ob das Socket noch aktiv ist, oder nicht und er killts dann. Anschließend gibt der Thread noch die Nachricht, dass alles ausgeführt wurde und verschwindet dann im Nirvana.
Danke dennoch für die Hilfe.
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Sa 04.11.06 22:18
Moin!
Wenn du des Umgangs mit Threads mächtig bist, warum nimmst du dann nicht gleich blocking-socket-calls?  Ist dann doch viel einfacher.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
marconist
      
Beiträge: 25
xp sp2
D5 pers
|
Verfasst: Sa 04.11.06 22:38
BAERnado hat folgendes geschrieben: | (Ich wünschte, hier wäre Delphi mal wie VB, wo die Eigenschaft Tag kein Integer, sondern ein String ist ) |
Hi,
Wo liegt denn das Problem?
In einen integer tag kann man auch die Adresse eines Strings übergeben.
srs,
marconist
|
|
BAERnado 
Hält's aus hier
Beiträge: 11
|
Verfasst: So 05.11.06 00:48
marconist hat folgendes geschrieben: |
Hi,
Wo liegt denn das Problem?
In einen integer tag kann man auch die Adresse eines Strings übergeben.
srs,
marconist |
Mit Speicherverwaltung bin ich unerfahren =(
|
|
|