Einzelnen Beitrag anzeigen

gandime
(Gast)

n/a Beiträge
 
#1

TClientSocket Windows-Socket-Fehler 10038?

  Alt 4. Jan 2009, 22: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