IdFTPServer在有客户连接的情况下,如何中断服务关闭服务器?

时间:2022-10-08 20:16:20
1:IdFTPServer在有客户连接的情况下,如何中断服务关闭服务器?
直接用IdFTPServer. Active:=False;会出错

2:如果有能判断出客户连接的方法也可以

3:权限设置的方法

20 个解决方案

#1


如果分不够,再开帖给分

#2


????

#3


1)修正Indy源码可以计解决,自己Debug到IdTCPServer.pas中处理
2)连接方式?都是TCP吧?
3)自己定义数据表处理

http://lysoft.7u7.net

#4


1、要服务器主动中断每个客户端的连接后关闭吧,我看他的demo里面,  
Clients         : TThreadList;
  try
    Clients.LockList.Add(NewClient);
  finally
    Clients.UnlockList;
  end;
用这个可以记录每个客户端的信息,关闭的时候,可以挨个把客户端线程断开,之后再关闭:
        with Clients.LockList do
        try
          for i := 0 to Count-1 do  // iterate through client-list
  begin
            RecClient := Items[i];           // get client-object
            RecThread := RecClient.Thread;     // get client-thread out of it
            RecThread.Connection.disconnect;
          end;
        finally
          Clients.UnlockList;
        end;
我也没有这样试过,不过觉得应该可以的。

#5


试试先!!!

#6


to  ly_liuyang(Liu Yang)
不知道怎样debug到IdTCPServer.pas中,即使调试到里面,又怎样解决问题呢
to  cjf1009(农民程序员) 
TIdpeerThread(LThreads[i]).connection.disconnectsocket
但是这样关闭了还是会出问题的

#7


TIdpeerThread(LThreads[i]).connection.disconnectsocket???????

没有这样用过。你去下载那个demo,看看应该就明白了。我觉得把所有客户端断开后再关闭就可以了。

#8


to  cjf1009(农民程序员) 
哪个DEMO? indy上的demo吗?

#9


???

#10


我有一个demo,如果要的话可以给我发信,我给你发就是了!

#11


刚看的:
indy关闭时产生的那个异常,不是错误。是因为一方断开连接,而另一方又试图访问的时候,就会产生那个异常。而如果不访问这个连接,就不会产生异常。正常的关闭过程是一方发送关闭信号,另一方收到后回应(其实我觉得不回应也可以),然后双方都断开。就像打电话,一方说拜拜,另一方说再见,然后都挂线,而如果一方什么都没说无缘无故挂线,那另一方就不知道怎么回事了。

调试时,indy会自动抛出这个异常,并且程序运行停止。

你知道该怎么做了?

#12


to cqwty(笨小孩) crystalgir@263.sina.com thanks!!!

#13


to cjf1009(农民程序员) 我知道indy关闭时产生的是异常,不是错误
我的做法可以采用一下以下两种:
1:  服务器关闭时,不发送消息到客户端,在这种情况下,即使是不在调试时,程序也会弹出一bug,
  不知道你有什么办法避免???
2:服务器关闭服务时,发送一消息到客户端,然后客户端端开连接,服务器的服务端开
   这种情况下我采用的是:
   服务器端
   function TfrmMain.StopIdftpServer: Boolean;
   const
     LSleepTime: Integer = 250; 
   var
     I: Integer;
     Threads: TThreadList;
     LThreads: TList;
     LTimedOut: Boolean;
   begin
     Result:= False;

     if MessageDlg('停止服务将导致数据不能上传,是否继续?',mtWarning,  mbYes,mbNo],0)       =mrNo then
      Exit;

    try
      Threads:= IdFTPServer1.Threads;
      if Assigned(Threads) then
      begin
        LThreads := Threads.LockList;
        try
          for i := 0 to LThreads.Count - 1 do
            TIdPeerThread(LThreads[i]).Connection.WriteBuffer('QUIT', Sizeof('QUIT'));
            //TIdPeerThread(LThreads[i]).FreeOnTerminate:= True;
            //TIdPeerThread(LThreads[i]).Terminate;
        finally
          Threads.UnlockList;
        end;
      end;

      Sleep(1000);
      IdFTPServer1.Active:= False;
      Result:= True;
    except
      MessageDlg('停止服务出现异常',mtWarning,[mbOk],0)
    end;

   end;

   客户端:
   我用的idftp,收到断开连接
   procedure TfrmMain.Timer1Timer(Sender: TObject);
   var
     buf: array[0..999] of Char;
     strAbort: String;
   begin
     IdFTP1.ReadBuffer(buf, Sizeof(buf));
     strAbort:= Strpas(buf);
     if strAbort= 'QUIT' then
     AbortTransfer:= True;
   end;
   我把idftp.readbuf放到了timer事件中,这样每次读取一次消息
   都会弹出一对话框(与idtcpclient组件不同),为了避免弹出对话框,我只能修改idftp控件了,
   不知道有没有其它的办法来解决这种问题?
   

#14


1、在程序里捕捉这个异常,自己做提示,好象也可以。不过那毕竟也说明程序没有写完美。
2、客户端接收服务器端的消息,可以建立一个线程。
可以单独建立一个线程来接收消息。
procedure TClienthandleThread.Execute;
begin
while not Terminated do
  begin
    if not MainForm.IdTCPClient1.Connected then
      Terminate
    else
      try
        recieve := MainForm.IdTCPClient1.ReadLn();
        Synchronize(HandleInput); //线程同步。我也只是做显示。不过这里的接收和server端的接收的命令处理的原理是一样的。
      except
        exit;
    end;//endif
  end;//endwhile
end;
不过这样退出的时候可能有点小问题,主要是断开连接后这个线程仍然存在,如果在断开前先把这个线程去掉,应该就没问题了。

#15


IdTCPClient和IdFTPClient应该是一样的。

#16


to cjf1009(农民程序员) 
1:如果能按你第一种说法做出来也行但是我不知道应该怎样处理
2:我测试了一下发现idftp与idtcpclient不一样
  idftp连接服务器后,然后idftp.readln就好象死机了一样
  不知道是什么问题

#17


idftp.ReadLn('',5);
或者放一个IdAntiFreeze就解决阻塞造成的窗口刷新问题

#18


to  cjf1009(农民程序员)  我写了个线程 象你那样处理
当我用客户端连接到服务器后 服务器端发送消息到客户端 
客户端断开连接 然后服务器关闭服务 此时也是会弹出bug的.
我测试了一下 服务器的线程数在客户端断开后并没有减少 郁闷 
即:    try
      Threads:= IdFTPServer1.Threads;
      if Assigned(Threads) then
      begin
        LThreads := Threads.LockList;
        LThreads.Count的数目在客户端断开的时候 也不会减少    

#19


你可以去下个indy的帮助文件去看看,上面也是这么说的,不行,我就不知道了。

#20


不过这个文件是英文的。搜搜应该会找到。

#1


如果分不够,再开帖给分

#2


????

#3


1)修正Indy源码可以计解决,自己Debug到IdTCPServer.pas中处理
2)连接方式?都是TCP吧?
3)自己定义数据表处理

http://lysoft.7u7.net

#4


1、要服务器主动中断每个客户端的连接后关闭吧,我看他的demo里面,  
Clients         : TThreadList;
  try
    Clients.LockList.Add(NewClient);
  finally
    Clients.UnlockList;
  end;
用这个可以记录每个客户端的信息,关闭的时候,可以挨个把客户端线程断开,之后再关闭:
        with Clients.LockList do
        try
          for i := 0 to Count-1 do  // iterate through client-list
  begin
            RecClient := Items[i];           // get client-object
            RecThread := RecClient.Thread;     // get client-thread out of it
            RecThread.Connection.disconnect;
          end;
        finally
          Clients.UnlockList;
        end;
我也没有这样试过,不过觉得应该可以的。

#5


试试先!!!

#6


to  ly_liuyang(Liu Yang)
不知道怎样debug到IdTCPServer.pas中,即使调试到里面,又怎样解决问题呢
to  cjf1009(农民程序员) 
TIdpeerThread(LThreads[i]).connection.disconnectsocket
但是这样关闭了还是会出问题的

#7


TIdpeerThread(LThreads[i]).connection.disconnectsocket???????

没有这样用过。你去下载那个demo,看看应该就明白了。我觉得把所有客户端断开后再关闭就可以了。

#8


to  cjf1009(农民程序员) 
哪个DEMO? indy上的demo吗?

#9


???

#10


我有一个demo,如果要的话可以给我发信,我给你发就是了!

#11


刚看的:
indy关闭时产生的那个异常,不是错误。是因为一方断开连接,而另一方又试图访问的时候,就会产生那个异常。而如果不访问这个连接,就不会产生异常。正常的关闭过程是一方发送关闭信号,另一方收到后回应(其实我觉得不回应也可以),然后双方都断开。就像打电话,一方说拜拜,另一方说再见,然后都挂线,而如果一方什么都没说无缘无故挂线,那另一方就不知道怎么回事了。

调试时,indy会自动抛出这个异常,并且程序运行停止。

你知道该怎么做了?

#12


to cqwty(笨小孩) crystalgir@263.sina.com thanks!!!

#13


to cjf1009(农民程序员) 我知道indy关闭时产生的是异常,不是错误
我的做法可以采用一下以下两种:
1:  服务器关闭时,不发送消息到客户端,在这种情况下,即使是不在调试时,程序也会弹出一bug,
  不知道你有什么办法避免???
2:服务器关闭服务时,发送一消息到客户端,然后客户端端开连接,服务器的服务端开
   这种情况下我采用的是:
   服务器端
   function TfrmMain.StopIdftpServer: Boolean;
   const
     LSleepTime: Integer = 250; 
   var
     I: Integer;
     Threads: TThreadList;
     LThreads: TList;
     LTimedOut: Boolean;
   begin
     Result:= False;

     if MessageDlg('停止服务将导致数据不能上传,是否继续?',mtWarning,  mbYes,mbNo],0)       =mrNo then
      Exit;

    try
      Threads:= IdFTPServer1.Threads;
      if Assigned(Threads) then
      begin
        LThreads := Threads.LockList;
        try
          for i := 0 to LThreads.Count - 1 do
            TIdPeerThread(LThreads[i]).Connection.WriteBuffer('QUIT', Sizeof('QUIT'));
            //TIdPeerThread(LThreads[i]).FreeOnTerminate:= True;
            //TIdPeerThread(LThreads[i]).Terminate;
        finally
          Threads.UnlockList;
        end;
      end;

      Sleep(1000);
      IdFTPServer1.Active:= False;
      Result:= True;
    except
      MessageDlg('停止服务出现异常',mtWarning,[mbOk],0)
    end;

   end;

   客户端:
   我用的idftp,收到断开连接
   procedure TfrmMain.Timer1Timer(Sender: TObject);
   var
     buf: array[0..999] of Char;
     strAbort: String;
   begin
     IdFTP1.ReadBuffer(buf, Sizeof(buf));
     strAbort:= Strpas(buf);
     if strAbort= 'QUIT' then
     AbortTransfer:= True;
   end;
   我把idftp.readbuf放到了timer事件中,这样每次读取一次消息
   都会弹出一对话框(与idtcpclient组件不同),为了避免弹出对话框,我只能修改idftp控件了,
   不知道有没有其它的办法来解决这种问题?
   

#14


1、在程序里捕捉这个异常,自己做提示,好象也可以。不过那毕竟也说明程序没有写完美。
2、客户端接收服务器端的消息,可以建立一个线程。
可以单独建立一个线程来接收消息。
procedure TClienthandleThread.Execute;
begin
while not Terminated do
  begin
    if not MainForm.IdTCPClient1.Connected then
      Terminate
    else
      try
        recieve := MainForm.IdTCPClient1.ReadLn();
        Synchronize(HandleInput); //线程同步。我也只是做显示。不过这里的接收和server端的接收的命令处理的原理是一样的。
      except
        exit;
    end;//endif
  end;//endwhile
end;
不过这样退出的时候可能有点小问题,主要是断开连接后这个线程仍然存在,如果在断开前先把这个线程去掉,应该就没问题了。

#15


IdTCPClient和IdFTPClient应该是一样的。

#16


to cjf1009(农民程序员) 
1:如果能按你第一种说法做出来也行但是我不知道应该怎样处理
2:我测试了一下发现idftp与idtcpclient不一样
  idftp连接服务器后,然后idftp.readln就好象死机了一样
  不知道是什么问题

#17


idftp.ReadLn('',5);
或者放一个IdAntiFreeze就解决阻塞造成的窗口刷新问题

#18


to  cjf1009(农民程序员)  我写了个线程 象你那样处理
当我用客户端连接到服务器后 服务器端发送消息到客户端 
客户端断开连接 然后服务器关闭服务 此时也是会弹出bug的.
我测试了一下 服务器的线程数在客户端断开后并没有减少 郁闷 
即:    try
      Threads:= IdFTPServer1.Threads;
      if Assigned(Threads) then
      begin
        LThreads := Threads.LockList;
        LThreads.Count的数目在客户端断开的时候 也不会减少    

#19


你可以去下个indy的帮助文件去看看,上面也是这么说的,不行,我就不知道了。

#20


不过这个文件是英文的。搜搜应该会找到。

#21