简体   繁体   English

了解 Indy Socket 超时

[英]Understanding Indy Socket timeouts

I want to understand how Indy socket timeouts works, because I want to use them in the following way.我想了解 Indy 套接字超时是如何工作的,因为我想以下列方式使用它们。

I have an application (TCP server/client) that transfers a file over the Internet.我有一个通过 Internet 传输文件的应用程序(TCP 服务器/客户端)。 When I start the transfer, I want to be able to stop it fast enough (let's say, 1500 ms) if I decide that.当我开始传输时,如果我决定这样做,我希望能够足够快地停止传输(比如说,1500 毫秒)。 If some socket is reading data, and something happens on the wire that makes it late, I won't be able to stop the transfer, because the socket is hung reading data.如果某个套接字正在读取数据,并且线路上发生了一些事情使它迟到了,我将无法停止传输,因为套接字挂起读取数据。 So I need to set some short timeouts, that in normal operation will not be triggered.所以我需要设置一些短暂的超时,在正常操作中不会被触发。 But if something happens and data is running late, the control will be passed to the main proc and I'll be able to check for the abort request.但是,如果发生某些事情并且数据运行延迟,则控制权将传递给主进程,我将能够检查中止请求。

Now, I don't know what to do next... If a socket read times out, what do that mean?现在,我不知道下一步该做什么......如果一个套接字读取超时,那是什么意思? The socket did not receive any data for that period of time... Or, the socket received some data in the buffer but doesn't have time to finish?套接字在那段时间没有收到任何数据......或者,套接字在缓冲区中接收了一些数据但没有时间完成? I have a feeling that those timeouts are the waiting periods for something to happen (start a read or a write operation).我有一种感觉,这些超时是发生某事的等待期(开始读取或写入操作)。 But (let's say a read), once started, what happens if the socket receives half of the data (which he was asked to read) and then nothing comes?但是(假设是一次读取),一旦开始,如果套接字接收到一半的数据(他被要求读取)然后什么都没有会发生什么? Will that call block the program execution forever?该调用会永远阻止程序执行吗? Because if that happens, then again I will not be able to check for abort request.因为如果发生这种情况,那么我将无法再次检查中止请求。

Anyway... when the timeout occurs, it will raise an exception?无论如何......当超时发生时,它会引发异常吗? I can catch it and try again, in the same connection, like nothing happened?我可以抓住它然后再试一次,在同一个连接中,就像什么都没发生一样? Will the in/out buffer be modified after a timeout?超时后是否会修改输入/输出缓冲区?

I am using this to set the Read and Write timeouts:我正在使用它来设置读取和写入超时:

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

Socket timeouts are applied on a per-byte basis.套接字超时按字节应用。

If you ask a socket to read N number of bytes, it will return as many bytes as it can, up to N bytes max, from the socket's receive buffer.如果您要求套接字读取 N 个字节,它将从套接字的接收缓冲区返回尽可能多的字节,最多 N 个字节。 It can (and frequently does) return fewer bytes, requiring another read to receive the remaining bytes.它可以(并且经常确实)返回更少的字节,需要另一个读取来接收剩余的字节。 If a timeout error occurs, it means no bytes at all arrived in time for the current read.如果发生超时错误,则意味着没有字节及时到达当前读取。 There is no way to know why, or whether they ever will arrive.没有办法知道为什么,或者他们是否会到达。

If you ask a socket to send N number of bytes, it will accept as many bytes as it can, up to N bytes max, into the socket's write buffer.如果你要求一个套接字发送 N 个字节,它会接受尽可能多的字节,最多 N 个字节,进入套接字的写缓冲区。 It can (and sometimes does) buffer fewer bytes, requiring another send to buffer the remaining bytes.它可以(有时确实)缓冲更少的字节,需要另一个发送来缓冲剩余的字节。 If a timeout occurs, it means the socket's write buffer has filled up, the receiver is not reading fast enough (or at all) to clear space in the sender's write buffer in time.如果发生超时,则意味着套接字的写入缓冲区已满,接收方读取速度不够快(或根本没有)以及时清除发送方写入缓冲区中的空间。

If you ask Indy to read/send N number of bytes, it may perform multiple socket reads/sends internally, waiting for all of the expected bytes to be received/sent.如果您要求 Indy 读取/发送 N 个字节,它可能会在内部执行多个套接字读取/发送,等待所有预期的字节被接收/发送。 So it may have read/sent X number of bytes, where X < N, before the timeout occured.因此,在超时发生之前,它可能已经读取/发送了 X 个字节,其中 X < N。 Sure, you could try another read/send again, asking for only the remaining bytes you haven't received/sent yet (N - X), but don't ask for the bytes you already received/sent (X).当然,您可以再次尝试另一次读取/发送,只询问您尚未接收/发送的剩余字节(N - X),但不要询问您已经接收/发送的字节(X)。 You might receive/send more bytes, or you might get another timeout, there is no way to know until you try.您可能会接收/发送更多字节,或者您可能会再次超时,除非您尝试,否则无法知道。 However, depending on context, it may not be easy/possible to know how many bytes were received/sent before the timeout, so you might not know how many remaining bytes to ask for again.但是,根据上下文,可能不容易/不可能知道在超时之前接收/发送了多少字节,因此您可能不知道要再次请求多少剩余字节。 In which case, about all you can sensibly do is just close the TCP connection, reconnect, and resume/start over.在这种情况下,您可以明智地做的就是关闭 TCP 连接,重新连接,然后恢复/重新开始。

As for your ability to abort a connection quickly, you could move your read/send code to a worker thread, and then Disconnect() the socket from your main proc when needed.至于快速中止连接的能力,您可以将读取/发送代码移动到工作线程,然后在需要时从主进程中Disconnect()套接字。 That will generally abort any blocking read/send in progress.这通常会中止任何正在进行的阻塞读取/发送。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM