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; }); }
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); }