如何正常关闭Indy10 ServerSocket实例?

时间:2013-07-16 20:02:43

标签: delphi indy indy10 delphi-xe4

我使用此代码段创建Indy10 TCPServer的新实例:

procedure TPortWindow.AddPort (Item : TListItem);
var
  Socket : TIdTcpServer;
begin
  Socket  := TIdTcpServer.Create(nil);
  try
    Socket.DefaultPort  := strtoint (item.Caption);
    Socket.OnConnect    := MainWindow.OnConnect;
    Socket.OnDisconnect := MainWindow.OnDisconnect;
    Socket.OnExecute    := MainWindow.OnExecute;
    Socket.Active       := TRUE;
  except
    Socket.Free;
    OutputError   ('Error','Port is already in use or blocked by a firewall.' + #13#10 +
                  'Please use another port.');
    Item.Data     := Socket;
    Item.Checked  := FALSE;
  end;
end;

我用它来删除实例:

procedure TPortWindow.RemovePort (Item : TListItem);
var
  Socket        : TIdTcpServer;
begin
  if Item.Data = NIL then Exit;
  Socket := TIdTcpServer(Item.Data);
  try
    Socket.Active := FALSE;
  finally
    Socket.Free;
  end;
  Item.Data := NIL;
end;

由于某种原因,实例不会停止监听,并且所有客户端都保持连接状态。当我尝试创建前一个端口的新实例(删除之后)时,它说该端口已经在使用,这意味着它没有停止监听。

如何正确关闭此实例(并断开所有连接的客户端)?

编辑:

procedure TMainWindow.OnConnect(AContext: TIdContext);
begin
  ShowMessage ('connected');
end;

procedure TMainWindow.OnDisconnect(AContext: TIdContext);
begin
  ShowMessage ('disconnected');
end;

procedure TMainWindow.OnExecute(AContext: TIdContext);
begin
 // Not defined yet.
end;

1 个答案:

答案 0 :(得分:4)

Active属性设置为False是正确的做法。它将自动关闭侦听端口并关闭所有活动的客户端连接。

但是,您需要注意的是确保您的服务器事件处理程序在主线程忙于停用服务器时未对主线程执行任何同步操作,否则将发生死锁。