了解 Indy Socket 超时

Understanding Indy Socket timeouts

我想了解 Indy 套接字超时是如何工作的,因为我想按以下方式使用它们。

我有一个通过 Internet 传输文件的应用程序 (TCP server/client)。当我开始传输时,如果我决定这样做,我希望能够足够快地停止传输(比如 1500 毫秒)。如果某个套接字正在读取数据,并且线路上发生某些事情导致延迟,我将无法停止传输,因为套接字已挂起读取数据。所以我需要设置一些短的超时,在正常操作中不会被触发。但是,如果发生某些事情并且数据 运行 延迟,控制权将传递给主进程,我将能够检查中止请求。

现在,我不知道下一步该怎么做...如果套接字读取超时,那是什么意思?套接字在那段时间没有收到任何数据......或者,套接字在缓冲区中收到了一些数据但没有时间完成?我有一种感觉,这些超时是等待某事发生的时间(开始读取或写入操作)。但是(假设是读取),一旦开始,如果套接字接收到一半数据(要求他读取)然后什么都没有发生怎么办?该调用会永远阻止程序执行吗?因为如果发生这种情况,我将再次无法检查中止请求。

总之...当超时发生时,它会抛出异常?我可以抓住它并在相同的连接中重试,就像什么都没发生一样? in/out缓冲区超时后会被修改吗?

我正在使用它来设置读写超时:

Socket.ReadTimeout:= WorkingRTimeOut;
Socket.Binding.SetSockOpt(SOL_SOCKET, SO_SNDTIMEO, WorkingWTimeOut);

套接字超时按字节应用。

如果您要求套接字读取 N 个字节,它将 return 从套接字的接收缓冲区中读取尽可能多的字节,最多 N 个字节。它可以(并且经常这样做)return 更少的字节,需要再次读取才能接收剩余的字节。如果发生超时错误,则意味着当前读取根本没有字节及时到达。没有办法知道为什么,或者他们是否会到达。

如果您要求套接字发送 N 个字节,它将接受尽可能多的字节,最多 N 个字节,进入套接字的写入缓冲区。它可以(有时确实)缓冲更少的字节,需要另一个发送来缓冲剩余的字节。如果发生超时,则意味着套接字的写入缓冲区已满,接收方的读取速度不够快(或根本没有),无法及时清除发送方写入缓冲区中的space。

如果您要求 Indy read/send N 个字节,它可能会在内部执行多个套接字 reads/sends,等待所有预期字节为 received/sent。因此在超时发生之前,它可能有 read/sent X 个字节,其中 X < N。当然,您可以再试一次 read/send,只询问您尚未 received/sent 的剩余字节 (N - X),但不要询问您已经 received/sent 的字节(X)。您可能会 receive/send 更多字节,或者您可能会再次超时,只有尝试才能知道。但是,根据上下文,可能无法 easy/possible 知道超时前 received/sent 有多少字节,因此您可能不知道要再次请求多少剩余字节。在这种情况下,您可以明智地做的就是关闭 TCP 连接,重新连接,然后 resume/start 结束。

至于快速中止连接的能力,您可以将 read/send 代码移至工作线程,然后在需要时 Disconnect() 来自主进程的套接字。这通常会中止任何正在进行的阻塞 read/send。