2016-07-20 107 views
-1

在我目前正在处理的应用程序中,如果我意识到这不是我要找的,我需要停止下载某个文件。在我开始接收文件之前,协议没有提供任何方式来知道它(如标题或其他)。中断通过套接字下载(recv)文件通过套接字

作为一个例子,在某些情况下,我可能正在寻找一个大小正确为X字节的文件,但是在我下载了X字节并继续获取更多字节后,这不是我正在寻找的文件其大小大于X.在这种情况下,我想停止下载以释放网络带宽资源。该协议不提供任何方式通知服务器这一点。

我在某处读取close(fd)shutdown(fd, SHUT_RD)将不会实际停止下载,因为服务器将继续send()该文件,这将继续消耗网络带宽。我也不确定如果我停止呼叫recv()并且数据包仍然到达,它们是否会填充缓冲区,然后开始丢弃?如果它很重要,则使用的协议基于TCP(但我希望某些解决方案也可用于基于UDP的协议)。

我就更加怀疑停止呼叫recv()会解决这个问题,我搜索了编程带宽控制(sleep(),令牌桶..)作为一种替代解决方案(降低下载速度接近零的我知道后后它不是我正在寻找的文件)。如果服务器仍然是send() ing,如何通过减少recv()调用来控制网络带宽使用情况?我没有抓住它。

主要想法是完全停止下载。

你会建议什么?

+2

TCP是基于连接的协议,所以基本上如果关闭连接,服务器将最终停止发送。 –

+2

是什么让你认为服务器会继续发送数据包?在最坏的情况下,当你关闭客户端套接字时,你的服务器在发送时会出现套接字错误,并停止发送数据。您对此类基本要求的细节过于担心。 – x82

+0

此外,请不要考虑使用UDP发送文件。 UDP是不可靠的,这意味着您甚至不会收到有关到达目的地的数据包的响应。这不是一个选项。 – x82

回答

1

我读的地方,close(fd)shutdown(fd, SHUT_RD)不会真正停止下载,服务器将继续send()文件,这将继续消耗网络带宽。

如果shutdown(fd, SHUT_RD)自己recv()将与零返回代码,这会导致代码以关闭插座,这将导致如果有更多的数据来自于同行,本地主机发出一个RST解除其将在发件人处引发一个ECONNRESET(在几个send()调用之后,不一定立即)。

你从哪里读到这个废话?

我就更加怀疑,如果停止调用recv()会解决它

它不会解决它,但它最终会从发送停止发送,因为TCP流量控制。这不是解决这个问题的方法。

+0

很好。我不太了解TCP。谢谢。关于这个废话:也许是关于UDP,我没有注意到...... –

+0

关于TCP流量控制:这意味着如果我减慢传输速度(通过减少'recv()'调用'sleep()')很多,是否有连接关闭的风险?或者这只适用于完全停止调用'recv()'? –

+1

如果您收到的邮件发送速度比发件人慢,发件人最终会被阻止,如果他处于阻止模式,或者EAGAIN/EWOULDBLOCK(如果他处于非阻止模式)。这包括根本没有收到的情况。 – EJP