예제 #1
0
Server::Server()
  : acceptSocket_(-1),
    port_(0),
    stop_(NO_STOP) {
  acceptSocket_ = socket(PF_INET, SOCK_STREAM, 0);
  CHECK_ERR(acceptSocket_);
  shutdownSocketSet.add(acceptSocket_);

  sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = 0;
  addr.sin_addr.s_addr = INADDR_ANY;
  CHECK_ERR(bind(acceptSocket_,
                 reinterpret_cast<const sockaddr*>(&addr),
                 sizeof(addr)));

  CHECK_ERR(listen(acceptSocket_, 10));

  socklen_t addrLen = sizeof(addr);
  CHECK_ERR(getsockname(acceptSocket_,
                        reinterpret_cast<sockaddr*>(&addr),
                        &addrLen));

  port_ = ntohs(addr.sin_port);

  serverThread_ = std::thread([this] {
    while (stop_ == NO_STOP) {
      sockaddr_in peer;
      socklen_t peerLen = sizeof(peer);
      int fd = accept(acceptSocket_,
                      reinterpret_cast<sockaddr*>(&peer),
                      &peerLen);
      if (fd == -1) {
        if (errno == EINTR) {
          continue;
        }
        if (errno == EINVAL || errno == ENOTSOCK) {  // socket broken
          break;
        }
      }
      CHECK_ERR(fd);
      shutdownSocketSet.add(fd);
      fds_.push_back(fd);
    }

    if (stop_ != NO_STOP) {
      closeClients(stop_ == ABORTIVE);
    }

    shutdownSocketSet.close(acceptSocket_);
    acceptSocket_ = -1;
    port_ = 0;
  });
}
예제 #2
0
void ClipboardServer::terminateClients(int waitMs)
{
    for (auto it = m_clients.constBegin(); it != m_clients.constEnd(); ++it) {
        const auto &clientData = it.value();
        if (clientData.isValid())
            clientData.client->sendMessage(QByteArray(), CommandStop);
    }

    waitForClientsToFinish(waitMs);
    emit closeClients();
    waitForClientsToFinish(waitMs / 2);
}