2013-07-16 38 views
0

我用这个片段创建Indy10 TCPSERVER的新实例:如何正常关闭Indy10 ServerSocket实例?

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; 
+2

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

回答

2

设置Active属性设为False是做正确的事。它会自动关闭侦听端口并关闭任何活动的客户端连接。

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

+0

对不起。它现在有效。非常感谢你。 –