J'ai adapté le code suivant d'un autre article sur ce site, mais il semble toujours se bloquer. Je dois être capable d'éteindre ou de déconnecter le serveur même s'il y a des clients connectés. Je vais attendre jusqu'à ce qu'ils finissent d'envoyer des messages, mais si je démarre le serveur, connectez-vous à partir d'un client, je ne peux toujours pas arrêter le serveur sans gel. Je dois ensuite éteindre avec Windows Task Manager.Delphi XE3, serveur TCP Indy. Arrêter le serveur
procedure TTasksForm.ShutDownPantherServer;
var i : integer ;
Context: TidContext;
begin
if PantherIdTCPServer.Active = True then
with PantherIdTCPServer.Contexts.LockList do
try
for i := (PantherIdTCPServer.Contexts.LockList.Count - 1) downto 0 do
begin
Context := Items[i] ;
if Context = nil then
Continue;
Context.Connection.IOHandler.WriteBufferClear;
Context.Connection.IOHandler.InputBuffer.Clear;
Context.Connection.IOHandler.Close;
if Context.Connection.Connected then
Context.Connection.Disconnect;
end;
finally
PantherIdTCPServer.Contexts.UnLockList ;
end ;
if PantherIdTCPServer.Active = True then
PantherIdTCPServer.Active := False ;
end;
informations Additonal ...
J'utilise le code suivant pour se connecter au serveur. Quand il se connecte le serveur renvoie un message qu'il y avait une connexion.
client Se connecter au serveur
procedure TPantherSimulatorForm.ConnectToServer ;
var MsgIn : String ;
begin
PantherIdTCPClient.Host := IPAddressEdit.Text ;
PantherIdTCPClient.Port := StrToInt(PortEdit.Text) ;
PantherIdTCPClient.Connect;
MsgIn := PantherIdTCPClient.IOHandler.ReadLn();
TThread.Synchronize(nil,
procedure
begin
ClientTrafficMemo.Clear ;
ClientTrafficMemo.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', now) +
' ' + MsgIn) ;
end) ;
end;
OnConnect sur le serveur
procedure TTasksForm.PantherIdTCPServerConnect(AContext: TIdContext);
begin
AContext.Connection.IOHandler.DefStringEncoding := Indy8BitEncoding ;
TThread.Synchronize(nil,
procedure
begin
ServerTrafficMemo.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', now) +
' OnConnect') ;
end);
// connected message
AContext.Connection.IOHandler.WriteLn('Connected');
end;
La combinaison de ces 2 procédures entraînera le serveur de geler lorsque je tente de fermer le programme serveur si je ne ferme pas bas le client d'abord. Je suis désolé, je suis trop nouveau pour Indy pour voir ce que le problème est ou comment faire le travail de thread pour résoudre le problème. J'espérais que vous verriez mon erreur débutants dans l'une des deux procédures de connexion.
Voici le code OnExecute:
procedure TForm2.PantherIdTCPServerExecute(AContext: TIdContext);
begin
Sleep(1000) ;
TThread.Queue(nil,
procedure
begin
ServerTrafficMemo.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', now) +
' OnExecute') ;
end) ;
end;
Je l'avais déjà essayé en me basant sur un autre message mais si un client s'est déjà connecté au serveur et si je fais PantherIdTCPServer.Active: = False alors j'essaye de fermer le formulaire le programme se bloque et ne se ferme pas. Si j'éteins le programme client qui était connecté puis éteins le serveur, je peux fermer le formulaire sans gel. Si le client s'est connecté et est toujours connecté et que j'arrête le serveur et ferme le formulaire, il se fige. Je n'ai pas d'événements OnClose ou OnCloseQuery sur le programme serveur. Il semble qu'il gèle jusqu'à ce que je déconnecte le client du client. –
Vous avez un problème d'interblocage, par exemple si vous désactivez le serveur du thread principal alors que le client effectue une synchronisation avec le thread principal.Le client sera bloqué en attente sur le thread principal, et le thread principal sera bloqué en attente sur le client. Le code que vous avez montré dans votre question souffre du même problème. Ainsi, soit ne pas synchroniser avec le thread principal lors de la désactivation du serveur dans le thread principal, soit désactiver le serveur à partir d'un thread de travail distinct afin que le thread principal ne soit pas bloqué. –
si j'affecte seulement un client par serveur, puisque le client est un dispositif médical fonctionnant sur un poste de travail, synchronise un problème. Juste curieux? –