【问题标题】:How can I gracefully shutdown an Indy10 ServerSocket Instance?如何优雅地关闭 Indy10 ServerSocket 实例?
【发布时间】:2013-07-16 20:02:42
【问题描述】:

我使用这个 sn-p 创建一个 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;

【问题讨论】:

  • 这些事件在工作线程中触发,但ShowMessage() 不是线程安全的。请改用Windows.MessageBox(),或将异步消息发布到主线程并让它显示消息框。

标签: delphi indy indy10 delphi-xe4


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2016-10-20
    • 2014-12-01
    • 2014-11-03
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 2015-06-25
    • 2013-04-27
    • 1970-01-01
    相关资源
    最近更新 更多