![]() |
TClientSocket Windows-Socket-Fehler 10038?
Hi,
ich habe einen Clienten und einen Server. Der Client soll anduernd versuchen eine Verbindung her zu stellen. Erklärung: 1. alles in '' bezeichnet den groben Ablauf des Programmes, wie es zum Fehler kommt
Delphi-Quellcode:
2. alles nach // bezeichnet die genauere Beschreibung des Codes
'Kommentar über den ablauf des Programmes'
Delphi-Quellcode:
Server:
//Nähere Codebeschreibung
Delphi-Quellcode:
Client:
var
SSCom:TServerSocket; SSDat:TServerSocket; procedure TFRDMain.FormDestroy(Sender: TObject);//Sobald das Programm geschlossen wird sollen alle Client eine Nachricht bekommen var I: Integer; begin for I := 0 to SSCom.Socket.ActiveConnections - 1 do begin SSCom.Socket.Connections[i].SendText('re') end; for I := 0 to SSDat.Socket.ActiveConnections - 1 do begin SSDat.Socket.Connections[i].SendText('re') end; end;
Delphi-Quellcode:
Sobald der Client einmal Connected ist und vom Server Disconnected wird und dann wieder versucht zum Server, der aber immer noch läuft, zu connecten bekomme ich folgenden Fehlermeldung:
var
CSCom: TClientSocket; CSDat: TClientSocket; BReconnect:boolean; SData:String; procedure TForm1.FormCreate(Sender: TObject);'1. Start'//Programmstart... begin application.OnException:=MainError; BReconnect:=false; Reset;//Die TCLientSockets einstellen/zurücksetzen CSCom.Active:=true; // der Client connectet zum Server end; Procedure TForm1.Reset;//ClientSocket einstellen/zurücksetzen var i: Integer; begin if assigned(CSCom) then//überprüfen ob einer der beiden ClientSockets schonmal benutz wurde begin CSCom.Active:=false;//wenn ja dann soll die Verbindung getrennt werden for i := 0 to 1000 do//Die Schleife steht hier, damit ich absolut sicher bin das der Client Disconnectet ist damit ich das als fehler ausschliesen konnte begin sleep(1); application.ProcessMessages; if CSCom.Active=false then//bei CSCom.active:=true; muss nämlich überprüft werden ob der Client schon connectet ist. begin //wenn man es nicht machen würde, würde der Code weiter laufen und der Client ist möglicherweise noch nicht connectet break; end; end; end; if assigned(CSCom) then begin CSDat.Active:=false; for i := 0 to 1000 do begin sleep(1); application.ProcessMessages; if CSDat.Active=false then break; end; end; CSCom.free;//Damit keine "Rückstände" von den Vorherigen Verbindungen den Fehler auslösen CSCom:=TClientSocket.create(nil);//Den ClientSocket wieder zuweisen und einstellen CSDat.free; CSDat:=TClientSocket.create(nil); CSCom.OnConnect:=CSComConnect; CSCom.OnDisconnect:=CSComDisconnect; CSCom.OnError:=CSComError; CSCom.OnRead:=CSComRead; CSDat.OnRead:=CSDatRead; CSCom.Host:=SHost; CSDat.Host:=SHost; CSCom.Port:=IPort; CSDat.Port:=IPort-1; SData:=''; end; procedure TForm1.Reconnect;'3. Hier Tritt denn der Fehler auf'//Der Client soll immer versuchen zu connecten var i:integer; begin if BReconnect=false then//damit der Code nicht zweimal ausgeführt wird z.B. duch einen OnDisconnect und vom Reconnect befehl vom Server begin BReconnect:=true; Reset;//Clients neu laden for I := 0 to 1000 do//Warten egl ist ein sehr viel höherer wert angegeben, aber ich will ja wissen wo der Fehler liegt ;-) begin sleep(1); application.ProcessMessages; end; BReconnect:=false; CSCom.Active:=true;'4. Fehler'//Hiernach kommt es zum Fehler end; end; procedure TForm1.MainError(Sender: TObject; E: Exception);//Socket Fehler und usw. begin if pos(uppercase('Socket-Fehler'),uppercase(e.Message))<>0 then//Sobald der Client keine Verbindung bekommen hat oder er irgendein anderer Socket-Fehler bekommt, soll eine Neue Verbindung versucht werden. begin Reconnect; end; end; procedure TForm1.CSComRead(Sender: TObject; Socket: TCustomWinSocket);'2. Den Disconnect Befehl ausführen'//OnRead für den Datenverker var SCommand:String; begin SCommand:=SData+socket.ReceiveText;//hier etwas verkürtz^^ if SCommand='re' then begin Reconnect; end; end; procedure TForm1.CSComDisconnect(Sender: TObject; Socket: TCustomWinSocket);//fals der Client Disconnectet wird begin Reconnect; end; procedure TForm1.CSComError(Sender: TObject; Socket: TCustomWinSocket;//bei Fehlern ErrorEvent: TErrorEvent; var ErrorCode: Integer); begin Reconnect; end; Zitat:
mfg gandime Edit: Komentare hinzugefügt im Code hinzugefügt |
Re: TClientSocket Windows-Socket-Fehler 10038?
Leider versteh ich den Code nicht...
Beispiel:
Delphi-Quellcode:
Das macht meines erachtens keinen Sinn: Die Schleife wird genau einmal durchlaufen, oder?
CSCom.Active:=false;
for i := 0 to 1000 do begin sleep(1); application.ProcessMessages; if CSCom.Active=false then begin break; end; end; Du könntest einfach noch beschreiben wie du dir den Ablauf deines Codes vorgestellt hast: Kommentare im Code wären dazu gut. |
Re: TClientSocket Windows-Socket-Fehler 10038?
Liste der Anhänge anzeigen (Anzahl: 1)
So ich hab die Komentare im Code hinzugefügt
weiterhin habe ich noch 1 2 sachen versucht und zwar habe ich den Reconnect Code Etwas verändert:
Delphi-Quellcode:
dadurch wird bei CSCom.Active:=true kein Fehler ausgeworfen aber der Client connectet nicht neu!
procedure TForm1.Reconnect;
var i:integer; begin if BReconnect=false then begin BReconnect:=true; // Reset; CSCom.Active:=false; for I := 0 to 1000 do begin sleep(1); application.ProcessMessages; end; BReconnect:=false; CSCom.Active:=true; end; end; Der auslöser des Fehlers muss also in Reset sein! Vlt durch das entbinden und wieder zuweisens von CSCom? Edit: habe ein verkeinfachtes Project im anhang, wo der Fehler auch entsteht! vlt hilft es ja |
Re: TClientSocket Windows-Socket-Fehler 10038?
So hab den genauen Fehler gefunden und jetzt bräuchte ich blos noch eine lösung^^
ich hoffe ich beschreibe alles richtig mit meinen leihen ausdrücken: Und zwar Wird auf das Objekt zugegriffen, obwohl es schon freigegeben (.free) ist. Dies ist der Fall, da der Reconnect Befehl entweder durch eine Socket-Nachricht oder durch den Disconnect des Clients ausgelöst wird. Blos wie erkenne ich ob auf das Objekt gerade zugegriffen wird oder nicht? Kann ich das Objekt auch freigeben, obwohl es gerade benutz wird? |
Re: TClientSocket Windows-Socket-Fehler 10038?
Also bis dato hab ich nur Zeit gefunden einen kleinen Blick in den Code zu werfen.
Ich sags ja nicht gerne aber ich glaube da steckt der Wurm drin. :duck: Was genau wolltest du erreichen? Server: Sendet Nachricht wenn er geschlossen wird. Client: Stellt Verbindung her. Bei Abbruch: Reconnect. So war es doch, oder? |
Re: TClientSocket Windows-Socket-Fehler 10038?
Ja der Client soll versuchen neu zu connecten, sobald die alte Verbindung beendet wurde beendet ist.
also bei OnDisconnect soll Reconnect ausgeführt werden. Dabei wird das Objekt (CsCom:TClientsocket) neu geladen, damit keine "Rückstände" der alten Verbindung zurück bleiben So sieht das zurücksetzten aus:
Delphi-Quellcode:
aber diese schleife wird von OnDisconnect aufgerufen, woduch CsCom noch verwendet wird, obwohl es schon freigegeben ist!
CsCom.free;
CsCom:=TClientsocket.create(nil); ... Zumindest glaube ich das es so ist. |
Re: TClientSocket Windows-Socket-Fehler 10038?
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab momentan leider kaum Zeit, daher hab ich einfach mal ein Beispielprojekt zusammengeklickt, welches genau das tut was du möchtest (siehe Anhang).
Prinzipiell leibt noch zu sagen: Die Socket-Kompos wurden nicht ohne Grund ab (wenn ich mich nicht irre) Delphi 7 rausgeworfen! Die Indy-Komponenten sind da eine gute Alternative. Die Umgewöhnung ist zwar meist schwierig aber es gibt gute Demos und Tutorials. Wenn du dich etwas genauer mit der Materie beschäftigen willst, kannst du auch direkt mit der WinAPI arbeiten. Ich habe dabei eine Menge gelernt... aber Vorsicht: Der Aufwand lohnt sich nur für Interessierte. Gruß Mr_G |
Re: TClientSocket Windows-Socket-Fehler 10038?
nen Timer... naja es funktioniert natürlich aber gefallen tut mir das nicht so umbeding!
Beim IdTCPClient hatte ich bis jetzt einfach zu viele Probleme! Darauf werde ich auf keinen fall wieder umsteigen! Damit kann man ja nichtmal vernünftig eine nachricht vom Server zum Clienten schicken, ohne die connection in einer While-schleife zu halten, was ich für sehr fragwürdig halt, da es mit den Winsocks ja auch ohne soetwas geht! Ich weiss nicht wie das bei der IdTCPClient komponennte aussieht ob die sich selbst identifiziert, wodurch sie für mich dann vollkommen unnütz ist! Gibt es denn keine andere Möglichkeit das problem zu beheben? edit: Ich hab auch schonmal versucht den ClientSocket als Thread zu starten, was super funktioniert! Allerdings hatte ich dann ein problem damit bei einem anderen Project wo laufen neune ClientSocket Threads gestartet und beendet wurde. dabei hatte ich selbsamerweise den selben Fehler konnte mir aber nicht erklären woher der gekommen ist... |
Re: TClientSocket Windows-Socket-Fehler 10038?
Was hast du gegen den Timer? Alternative wäre das Socket auf ctBlocking zu stellen aber das gefällt dir bestimmt nicht ;)
Schau dir doch einfach mal die Indy-Demos an. So kompliziert ist das gar nicht. Wenn man das System vestanden hat bietet es sogar mehr Möglichkeiten. |
Re: TClientSocket Windows-Socket-Fehler 10038?
hmm was macht denn ctBlocking?
ja dann gib mir doch mal nen ganz einfaches beispiel wie ich ne nachricht vom server zum clienten schicke ohne eine While schleife beim connecten?! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz