AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi TClientSocket Windows-Socket-Fehler 10038?
Thema durchsuchen
Ansicht
Themen-Optionen

TClientSocket Windows-Socket-Fehler 10038?

Ein Thema von gandime · begonnen am 4. Jan 2009 · letzter Beitrag vom 6. Jan 2009
Antwort Antwort
gandime
(Gast)

n/a Beiträge
 
#1

TClientSocket Windows-Socket-Fehler 10038?

  Alt 4. Jan 2009, 23:42
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
'Kommentar über den ablauf des Programmes' 2. alles nach // bezeichnet die genauere Beschreibung des Codes
//Nähere Codebeschreibung Server:
Delphi-Quellcode:
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;
Client:
Delphi-Quellcode:
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='rethen
  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;
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:
Zitat:
Erste Gelegenheit für Exception bei $7C812AEB. Exception-Klasse ESocketError mit Meldung 'Windows-Socket-Fehler: Ein Vorgang bezog sich auf ein Objekt, das kein Socket ist (10038), bei API 'connect''. Prozess PRDClient.exe (1988)
Das erstaunlich ist auch, das MainError nicht ausgelöst wird!

mfg
gandime

Edit:
Komentare hinzugefügt im Code hinzugefügt
  Mit Zitat antworten Zitat
Benutzerbild von Mr_G
Mr_G

Registriert seit: 2. Sep 2004
Ort: Duisburg
468 Beiträge
 
Delphi 2006 Professional
 
#2

Re: TClientSocket Windows-Socket-Fehler 10038?

  Alt 5. Jan 2009, 00:30
Leider versteh ich den Code nicht...
Beispiel:
Delphi-Quellcode:
CSCom.Active:=false;
for i := 0 to 1000 do
begin
  sleep(1);
  application.ProcessMessages;
  if CSCom.Active=false then
  begin
    break;
  end;
end;
Das macht meines erachtens keinen Sinn: Die Schleife wird genau einmal durchlaufen, oder?
Du könntest einfach noch beschreiben wie du dir den Ablauf deines Codes vorgestellt hast: Kommentare im Code wären dazu gut.
Jan
  Mit Zitat antworten Zitat
gandime
(Gast)

n/a Beiträge
 
#3

Re: TClientSocket Windows-Socket-Fehler 10038?

  Alt 5. Jan 2009, 03:23
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:
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;
dadurch wird bei CSCom.Active:=true kein Fehler ausgeworfen aber der Client connectet nicht neu!

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
Angehängte Dateien
Dateityp: zip connection_fehler_test_545.zip (471,3 KB, 8x aufgerufen)
  Mit Zitat antworten Zitat
gandime
(Gast)

n/a Beiträge
 
#4

Re: TClientSocket Windows-Socket-Fehler 10038?

  Alt 5. Jan 2009, 19:30
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?
  Mit Zitat antworten Zitat
Benutzerbild von Mr_G
Mr_G

Registriert seit: 2. Sep 2004
Ort: Duisburg
468 Beiträge
 
Delphi 2006 Professional
 
#5

Re: TClientSocket Windows-Socket-Fehler 10038?

  Alt 5. Jan 2009, 19:34
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.
Was genau wolltest du erreichen?
Server: Sendet Nachricht wenn er geschlossen wird.
Client: Stellt Verbindung her. Bei Abbruch: Reconnect.
So war es doch, oder?
Jan
  Mit Zitat antworten Zitat
gandime
(Gast)

n/a Beiträge
 
#6

Re: TClientSocket Windows-Socket-Fehler 10038?

  Alt 5. Jan 2009, 20:07
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:
CsCom.free;
CsCom:=TClientsocket.create(nil);
...
aber diese schleife wird von OnDisconnect aufgerufen, woduch CsCom noch verwendet wird, obwohl es schon freigegeben ist!
Zumindest glaube ich das es so ist.
  Mit Zitat antworten Zitat
Benutzerbild von Mr_G
Mr_G

Registriert seit: 2. Sep 2004
Ort: Duisburg
468 Beiträge
 
Delphi 2006 Professional
 
#7

Re: TClientSocket Windows-Socket-Fehler 10038?

  Alt 6. Jan 2009, 00:42
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
Angehängte Dateien
Dateityp: rar test_107.rar (372,5 KB, 20x aufgerufen)
Jan
  Mit Zitat antworten Zitat
gandime
(Gast)

n/a Beiträge
 
#8

Re: TClientSocket Windows-Socket-Fehler 10038?

  Alt 6. Jan 2009, 16:52
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...
  Mit Zitat antworten Zitat
Benutzerbild von Mr_G
Mr_G

Registriert seit: 2. Sep 2004
Ort: Duisburg
468 Beiträge
 
Delphi 2006 Professional
 
#9

Re: TClientSocket Windows-Socket-Fehler 10038?

  Alt 6. Jan 2009, 17:30
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.
Jan
  Mit Zitat antworten Zitat
gandime
(Gast)

n/a Beiträge
 
#10

Re: TClientSocket Windows-Socket-Fehler 10038?

  Alt 6. Jan 2009, 18:51
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?!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz