问题描述
当我知道我希望从客户端获得多少字节时(在此代码中为100),我遇到了这种情况.如果客户不给我100,我根本就不需要此数据包,因为它已损坏.
I have situation when I know how much bytes I expect to get from client (in this code it is 100). If client does't gives me 100 I don't need this packet at all, because it is corrupted.
当客户端提供少于100个字节并断开连接时,我遇到了这种情况.在这种情况下,我捕获到异常,并且一切都会好起来,除了在此异常之后,我的 ServerTCPExecute
被不连续地调用了很多次.没有其他任何客户端连接.为什么会这样呢?如果我这样做 TIdYarnOfThread(AContext.Yarn).Thread.Terminate;
一切都会好起来.但是我不确定这是个好解决方案.
I have situation when client gives less than 100 bytes and disconnects. In this case I'm catching exception and everything would be fine except that after this exception my ServerTCPExecute
is called for many times uncontinuously. There are no any other clients connected. Why it is so? If I do TIdYarnOfThread(AContext.Yarn).Thread.Terminate;
everything goes fine. But I'm not sure it is good solution.
procedure Form1.ServerTCPExecute(AContext: TIdContext);
begin
try
AContext.Connection.IOHandler.ReadBytes(b, 100, False);
except
//TIdYarnOfThread(AContext.Yarn).Thread.Terminate;
end;
end;
推荐答案
解决方案:请勿使用 try ...除外
来捕获和忽略 OnExecute
中的所有异常.
Solution: do not use try ... except
to catch and ignore all exceptions within OnExecute
.
这将吞噬Indy异常,该异常在客户端断开连接时发生,如果 IOHandler.InputBuffer
中仍然有数据,服务器将执行 OnExecute
的下一次迭代,和 ReadBytes
引发另一个异常,因为对等方断开连接.
This will swallow the Indy exception which happens when the client disconnects, the server will execute the next iteration of OnExecute
if the IOHandler.InputBuffer
still has data in it, and ReadBytes
raises another exception because the peer disconnected.
如果引发任何异常并退出该方法,则Indy TCP服务器将关闭并清理连接.
If any exception is raised and leaves the method, the Indy TCP server will close and clean up the connection.
Indy在 OnExecute
中将异常用于错误处理和通知,因此请不要使用空"异常处理程序来抑制它们.如果需要捕获异常,请重新捕获捕获的所有 EIdException
派生的异常,然后由服务器处理.
Indy uses exceptions for error handling and notifications in OnExecute
, so do not suppress them with an "empty" exception handler. If you need to catch exceptions, re-raise any EIdException
-derived exceptions you catch and let the server handle them.
p.s .:发布的代码似乎使用了非本地变量 b
.因为 TIdTCPServer
是多线程组件,所以必须始终以线程安全的方式访问非局部变量,例如使用关键部分,或将变量放入 TIdContext
对象.
p.s.: the posted code seems to use a non-local variable b
. Because TIdTCPServer
is a multi-threaded component, non-local variables must always be accessed in a thread-safe way, for example using a critical section, or putting the variable inside of the TIdContext
object.
这篇关于客户端断开连接后,Indy服务器TIdTCPServer.OnExecute连续调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!