Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 异步套接字和;“沉默”;断开_Cocoa_Sockets_Asyncsocket_Casyncsocket - Fatal编程技术网

Cocoa 异步套接字和;“沉默”;断开

Cocoa 异步套接字和;“沉默”;断开,cocoa,sockets,asyncsocket,casyncsocket,Cocoa,Sockets,Asyncsocket,Casyncsocket,我一直在使用cocoaasyncsocket作为使用asyncsocket的Windows.net服务器的客户端。我正在使用ProtocolBuffers对消息进行编码。这些组合在一起构成了一套很棒的工具 然而,最近我注意到,如果我在尝试请求数据时让客户端与服务器连接很长时间(很多小时),消息似乎会被发送,但从未到达服务器。我称之为“无声”断开连接,因为我没有收到通常的断开连接,如果出现网络问题,我会这样做 在调试过程中,我正在处理以下方法,但没有一个被调用: - (NSTimeInterval

我一直在使用cocoaasyncsocket作为使用asyncsocket的Windows.net服务器的客户端。我正在使用ProtocolBuffers对消息进行编码。这些组合在一起构成了一套很棒的工具

然而,最近我注意到,如果我在尝试请求数据时让客户端与服务器连接很长时间(很多小时),消息似乎会被发送,但从未到达服务器。我称之为“无声”断开连接,因为我没有收到通常的断开连接,如果出现网络问题,我会这样做

在调试过程中,我正在处理以下方法,但没有一个被调用:

- (NSTimeInterval)onSocket:(AsyncSocket *)sock
  shouldTimeoutReadWithTag:(long)tag
                   elapsed:(NSTimeInterval)elapsed
                 bytesDone:(CFIndex)length {

- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err

- (void)onSocketDidDisconnect:(AsyncSocket *)sock
在没有任何通知的情况下,我发现这很难调试。服务器同样不显示任何断开连接

有谁能为我指出如何进一步分析这个问题的方向吗


非常感谢。

如果你想知道你的客户机和服务器已连接,你必须有心跳信号或“keepalive”,即一条应用程序级消息,它的交换基本上是说“你在吗”/“是”

现在尤其如此,因为许多路由器会悄悄地丢弃空闲的TCP连接。这不是TCP设计的目的,但却是生活中的事实

TCP可以选择发送连接层heartbeat或使用SO_keepalive发送keepalive,但从历史上看,这是否合适存在争议。设计人员认为,由于临时的中间网络问题而丢弃套接字是错误的。如果在此期间没有实际发送数据,则没有理由中断连接。另一些人认为,了解这种联系是否良好本身就很重要。如果您期望数据,但数据尚未到达,该怎么办?你不想知道吗

最终取决于应用程序。如果“无新信息”是对应用程序很重要的事实的断言(例如,新闻提要、销售订单、市场数据价格变化),则需要检查“无新信息”是否为真正的“无新信息”,而不是“连接被悄悄删除”。这意味着一个明确的信息

那么你应该多久发送一次


这取决于事物的平衡。1a)您通常多久获得一次更新?1b)什么样的延迟是可接受的/正常的(例如,如果这是流程的一部分,其他步骤通常需要数小时,那么5-10分钟可能是可接受的)。2a)电池和2b)心跳导致的数据使用。我怀疑对电池/电源的影响将是至关重要的,但所有这些都需要仔细研究,并保持平衡


毕竟,你随时都可能失去保险(隧道等)。只有在平均更新间隔的0.5到5倍之间没有更新时,我才会运行heartbeat。所以,如果你希望每分钟更新2次,那么在空闲的情况下运行心跳15秒到3分钟——判断什么是最好的。如果用户在应用程序中处于“活动”状态,并且完成后“关闭”,那么电池寿命就不是问题,因为他们正在使用它。如果要唤醒设备处理更新,电池寿命确实是个问题。

我希望这不是答案。这是一个移动应用程序,定期发送“ping”消息似乎是浪费。我应该实现SO_KEEPALIVE还是构建自己的协议?如果您有其他信息可以在心跳期间有效地交换,那么使用应用程序级别的协议。否则,SO_KEEPALIVE就可以了,但您必须使用SIO_KEEPALIVE_VALS设置所需的KEEPALIVE间隔,因为默认值为2小时,我怀疑这会太长。我们实现了一个非常简单的应用程序级别1,因为asyncsockets使其变得非常简单。现在的问题是时机。对于一个将在移动设备上使用的应用程序,什么是好的使用间隔?这取决于事物的平衡。1a)您通常多久获得一次更新?1b)什么样的延迟是可接受的/正常的(例如,如果这是流程的一部分,其他步骤通常需要数小时,那么5-10分钟可能是可接受的)。2a)电池和2b)心跳导致的数据使用。我怀疑对电池/电源的影响将是至关重要的,但所有这些都需要仔细研究,并保持平衡。这是一个股票交易应用程序,因此延迟非常重要。该应用程序没有任何其他定期运行的功能,只有这个keepalive进程。我想我需要提出这样一个问题:“在发送此keepalive之前,我能等待并知道我不会断开连接的最长时间是多少?”您是否找到了使套接字长期处于活动状态的有效解决方案?