/*..........................................................................*/ static DWORD WINAPI idleThread(LPVOID par) {/* signature for CreateThread() */ (void)par; l_running = (uint8_t)1; while (l_running) { Sleep(10); /* wait for a while */ if (_kbhit()) { /* any key pressed? */ char payload[1024]; if(!gets_s(payload, sizeof(payload))) { // EOF reached printf("EOF received; exiting\n"); QF_stop(); } else { uint16_t len = strlen(payload); onPacket(payload, len, BSPConsole_print, NULL); } } #ifdef Q_SPY { uint16_t nBytes = 1024; uint8_t const *block; QF_CRIT_ENTRY(dummy); block = QS_getBlock(&nBytes); QF_CRIT_EXIT(dummy); if (block != (uint8_t *)0) { send(l_sock, (char const *)block, nBytes, 0); } } #endif } return 0; /* return success */ }
int ZMQTransport::dispatch(boost::chrono::milliseconds timeout) { zmq::pollitem_t items[] = { { _socket, 0, ZMQ_POLLIN, 0 } }; BOOST_LOG_TRIVIAL(debug) << "Polling zmq"; int result = zmq::poll(items, 1, timeout.count()); if (result > 0) { BOOST_LOG_TRIVIAL(debug) << "... Received"; zmq::message_t msg; _socket.recv(&msg); Packet p(msg.size()); ::memcpy(p.data(), msg.data(), msg.size()); onPacket(p); } return result; }
void CDatagrams::onReceiveGND() { GND_HEADER* pHeader = (GND_HEADER*)m_pRecvBuffer->data(); QHostAddress nIp = *m_pHostAddress; quint32 nSeq = ((pHeader->nSequence << 16) & 0xFFFF0000) + (m_nPort & 0x0000FFFF); #ifdef DEBUG_UDP systemLog.postLog(LogSeverity::Debug, "Received GND from %s:%u nSequence = %u nPart = %u nCount = %u", m_pHostAddress->toString().toLocal8Bit().constData(), m_nPort, pHeader->nSequence, pHeader->nPart, pHeader->nCount); #endif DatagramIn* pDatagramIn = 0; if(m_RecvCache.contains(nIp) && m_RecvCache[nIp].contains(nSeq)) { pDatagramIn = m_RecvCache[nIp][nSeq]; // To give a chance for bigger packages ;) if(pDatagramIn->m_nLeft) { pDatagramIn->m_tStarted = time(0); } } else { QMutexLocker l(&m_pSection); if(!m_FreeDatagramIn.isEmpty()) { pDatagramIn = m_FreeDatagramIn.takeFirst(); } else { if(m_FreeDatagramIn.isEmpty()) { removeOldIn(true); if(m_FreeDatagramIn.isEmpty()) { #ifdef DEBUG_UDP systemLog.postLog(LogSeverity::Debug, QString("UDP in frames exhausted")); #endif m_nDiscarded++; return; } } pDatagramIn = m_FreeDatagramIn.takeFirst(); } if(m_FreeBuffer.size() < pHeader->nCount) { m_nDiscarded++; m_FreeDatagramIn.append(pDatagramIn); removeOldIn(false); return; } pDatagramIn->create(CEndPoint(*m_pHostAddress, m_nPort), pHeader->nFlags, pHeader->nSequence, pHeader->nCount); for(int i = 0; i < pHeader->nCount; i++) { Q_ASSERT(pDatagramIn->m_pBuffer[i] == 0); pDatagramIn->m_pBuffer[i] = m_FreeBuffer.takeFirst(); } m_RecvCache[nIp][nSeq] = pDatagramIn; m_RecvCacheTime.prepend(pDatagramIn); } // It is here, in case if we did not have free datagrams // ACK = I've received a datagram, and if you have received and rejected it, do not send ACK-a if(pHeader->nFlags & 0x02) { GND_HEADER* pAck = new GND_HEADER; memcpy(pAck, pHeader, sizeof(GND_HEADER)); pAck->nCount = 0; pAck->nFlags = 0; #ifdef DEBUG_UDP systemLog.postLog(LogSeverity::Debug, "Sending UDP ACK to %s:%u", m_pHostAddress->toString().toLocal8Bit().constData(), m_nPort); #endif //m_pSocket->writeDatagram((char*)&oAck, sizeof(GND_HEADER), *m_pHostAddress, m_nPort); //m_mOutput.Add(sizeof(GND_HEADER)); m_AckCache.append(qMakePair(CEndPoint(*m_pHostAddress, m_nPort), reinterpret_cast<char*>(pAck))); if( m_AckCache.count() == 1 ) QMetaObject::invokeMethod(this, "flushSendCache", Qt::QueuedConnection); } if(pDatagramIn->add(pHeader->nPart, m_pRecvBuffer->data() + sizeof(GND_HEADER), m_pRecvBuffer->size() - sizeof(GND_HEADER))) { G2Packet* pPacket = 0; try { CEndPoint addr(*m_pHostAddress, m_nPort); pPacket = pDatagramIn->toG2Packet(); if(pPacket) { onPacket(addr, pPacket); } } catch(...) { } if(pPacket) { pPacket->release(); } m_pSection.lock(); remove(pDatagramIn, true); m_pSection.unlock(); } }
/** accepts and keeps track of connections. reads data from connected peers and notifies through virtual methods if packets can be deserialized \param tls use GnuTLS for encryption \param port listen for incoming connections at this port \param maxPeers maximum number of connected peers */ void serve(bool tls, int port, int maxPeers) { if (tls) sock.reset(new TLSSocket()); else sock.reset(new Socket()); sock->setNonBlocking(); sock->bind(port); sock->listen(maxPeers); Select select; /* Wait for a peer, send data and term */ while (!closed) { select.reset(); if (peers.size() < maxPeers) select.input(sock->getFd()); for (typename Peers::iterator i = peers.begin(); i != peers.end(); i++) { select.input((*i)->getFd()); } if (select.select(100) == -1) continue; if (select.canRead(sock->getFd()) && peers.size() < maxPeers) { try { Socket* csock = sock->accept(); if (tls) { boost::threadpool::schedule(pool, boost::bind(&Server::handshake, this, csock)); } else { peers.push_back(boost::shared_ptr<PeerT>(new PeerT())); csock->setNonBlocking(); peers.back()->setup(csock); onJoin(*peers.back()); } } catch (SocketExcept& e) { std::cerr << e.what() << std::endl; } } if (tls) { Socket* sock = NULL; socketsReady.try_pop_front(sock); if (sock) { sock->setNonBlocking(); peers.push_back(boost::shared_ptr<PeerT>(new PeerT())); peers.back()->setup(sock); onJoin(*peers.back()); } } for (size_t i = 0; i < peers.size(); i++) { boost::shared_ptr<PeerT>& p = peers[i]; if (select.canRead(p->getFd())) p->onInput(); while (p->hasPacket()) { onPacket(*p); } } // collect dead peers size_t count = peers.size(); for (size_t i = 0; i < count; ) { if (!peers[i]->isActive()) { onLeave(*peers[i]); peers[i] = peers[peers.size() - 1]; count--; } else i++; } if (count < peers.size()) { peers.resize(count); } } }