检查插座是否关闭

时间:2016-02-13 19:56:37

标签: c++ linux sockets

我有一个连接到某个服务器的应用程序。它可以同步发送数据(发送和等待应答)并异步接收数据。 我做了2个帖子。在无限循环的第一个线程中,我发送数据并等待回答。在第二个线程中,我正在从服务器中导入数据并将它们推入队列中。 但是,如果在发送数据时发生了一些错误(在第一个线程中),我必须关闭套接字。如何在第二个线程中检查套接字是否已关闭?

第二个帖子中的代码:

while (processing) {
  nbytes = recv(socketDesc, canFrame, sizeof(data), 0);
  if (nbytes > 0) {
    push_queue(data);
  }
  if (nbytes < 0) {
    throw "Error in read data from socket!";
  }
}

如果我在第二个线程函数recv的第一个线程中关闭套接字,则不会出错。现在我使用超时,就像这样:

setsockopt(this->socketDesc, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
  setsockopt(this->socketDesc, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv));

当我没有从服务器(在第一个线程中)得到答案时发生错误我将变量processing设置为false,并且在超时到期后(在函数recv中)循环结束。我可以在函数recv中一次检查套接字关闭吗?

2 个答案:

答案 0 :(得分:1)

没有及时的方法来确定您已关闭套接字。您需要在两个线程之间共享并由互斥锁保护的变量。第一个线程可以设置变量,如果它关闭套接字,第二个线程应该在执行recv之前检查它。

答案 1 :(得分:1)

以下是确保在读取线程正在读取时不关闭套接字的方法。

您有2个受互斥锁保护的共享布尔变量:

bool reading = false;
bool closed = false;

对这些访问的所有访问都先锁定互斥锁,然后解锁它。

写作主题:

  1. 写入
  2. 如果写入失败:
    1. closed设为true
    2. 等待reading成为false
    3. 关闭套接字
  3. 阅读主题:

    1. 检查closed不是true。如果不是:
      1. reading设为true
      2. 读取
      3. reading设为false