Select()不会在客户端出现

时间:2012-10-10 07:49:46

标签: sockets

我只使用linux套接字编写了一个客户端套接字程序。这是给出了我在我的程序中正在做什么的信息

  1. 创建套接字
  2. 与服务器套接字建立连接
  3. 将该套接字分配给select set的读取集和异常集。
  4. 使用select方法在单独的线程中给出超时值NULL
  5. 服务器在一个外部设备中运行。

    这个程序适用于阅读和所有..现在当我拔掉该设备的电源线时,我遇到了问题。

    我假设当我们移除设备的电源线时,所有套接字将突然关闭,连接的客户端套接字将获得读取事件。当我们尝试读取时,我们会收到读取为零的字节数,这意味着连接由服务器关闭。

    但在我的程序中,当我拔掉设备的电源线时,在我的客户端程序中选择不出来意味着客户端套接字没有得到任何事件。我不明白为什么..

    关于我们如何知道服务器关闭连接或关闭电源时套接字行为的任何信息,我们将不胜感激。

    我需要你的帮助,非常关键。

    谢谢你。

1 个答案:

答案 0 :(得分:1)

当远程机器突然切断网络(网络电缆拔出或断电)时,无法通知对方连接。更重要的是,只执行从半开放套接字读取的客户端(就像你的情况一样)也无法检测到这一点。

了解连接丢失的唯一方法是发送数据包。由于所有正在发送的数据都应该由另一方确认,因此客户端计算机上的TCP将继续重试以发送未经证实的数据部分,直到尝试次数耗尽为止。然后应该返回ETIMEDOUT错误(通过期望读取事件的套接字)。您可以再创建一个套接字来定期发送这些消息,以检测客户端的对等消失(心跳连接)。但所有这些重试可能还需要一些时间。

另一种选择可能是使用SO_KEEPALIVE套接字选项。连接空闲一段时间后,TCP开始向服务器发送探测消息,并可以检测到它的消失。空闲项的默认值通常非常大,因此需要进行修改。一些可能相关的其他参数(TCP_KEEPCNT,TCP_KEEPINTVL,TCP_KEEPIDLE)。看来,这个选项可能在不同的系统上实现不同,或者可能根本不存在。

我从未亲自尝试解决这个问题,所以这只是一堆可能会提出一些想法的想法。这是另外一个source of ideas