检查服务器是否在超时后收到数据

时间:2015-12-13 09:46:13

标签: c++ asp.net-web-api libcurl

我制作了一个程序,它使用了几个比特币交换的RestAPI,例如Bitstamp

有一项功能允许我进行交易:以特定价格出售或购买比特币。简化后,您必须使用以下参数调用URL:

https://www.bitstamp.net/api/trade?price=100&amount=1&type=sell

然后服务器以JSON回答。例如:

{"error":"","message":"Sold 1 BTC @ 100$"}

如果交易成功,我的计划将继续。如果不是,则再次尝试(取决于错误消息)。

然而,有一个问题。我正在使用libcurl与服务器进行通信,并将CURLOPT_TIMEOUT设置为两秒钟。它几乎总是有效,但有时我会收到以下错误:

Code #28: Operation timed out after 2000 milliseconds with 0 bytes received

当发生这种情况时,我的程序会再次尝试交易。但有时,尽管超时,交易已经完成,这意味着它已经多次完成,因为我的代码再次尝试。

我可以以某种方式查明服务器是否至少收到了所有数据?问题是如果我将CURLOPT_TIMEOUT增加到10秒,而服务器没有回答,我也有同样的问题。所以这不是一个解决方案。

2 个答案:

答案 0 :(得分:2)

我不知道Bitstamp的细节,但这里是HTTP的工作原理。客户端向服务器发送请求并接收响应。在响应中,描述了有关成功或失败的详细信息(使用HTTP错误代码)。但是,如果收到超时,则客户端没有关于它的请求的信息:

  • 是否已发送到服务器;
  • 服务器收到了它;
  • 如果服务器收到请求,它是否设法处理;
  • 也许服务器处理了请求,但由于网络问题,发送回响应失败。

出于这个原因,不应该认为请求是成功的,并且应该重新发送请求。您描述的问题当然是可能的 - 服务器收到请求,处理它但没有设法发回响应。出于这个原因,应该使用其他更复杂的协议,遗憾的是,由于它的请求 - 响应性质,HTTP不是其中之一。

也许您应该检查给定的REST API是否给出了事务的某些状态。

答案 1 :(得分:1)

应该等待HTTP响应更加确定您的请求是否成功处理。

如果您可以访问文件描述符,可以使用ioctl()(Linux)或SIOCOUTQ(BSD)调用FIONWRITE - 我不知道Windows的等价物 - ,在完全中止连接之前检查套接字级别未确认的已发送数据。

问题在于它也不会完全没有错误。即使TCP在传输级别是有状态的,HTTP在应用程序级别也是无状态的。如果你的应用程序需要交易行为(你处理货币,毕竟不是吗?),它应该提供一种方法。

所有这一切,我认为两秒钟可能太少了。如果由于多次操作或类似操作而需要速度,请考虑并行化连接。