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='
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;
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