void Tunnelc::onENetPeerConnected(ENetHost *enhost, ENetPeer *enpeer, quint32 data) { qDebug()<<enhost<<enpeer<<data; // ToxTunChannel *chan = this->m_enpeer_chans[enpeer]; // ToxTunChannel *chan = (ToxTunChannel*)enpeer->toxchan; ToxTunChannel *chan = peerLastChan(enpeer); // enet_peer_ping_interval() // enet_peer_ping( enet_peer_timeout(enpeer, UINT32_MAX/*ENET_PEER_TIMEOUT_LIMIT * 0xfffff*/, UINT32_MAX/*ENET_PEER_TIMEOUT_MINIMUM * 0xffff*/, UINT32_MAX/*ENET_PEER_TIMEOUT_MAXIMUM * 0xffff*/); enet_peer_ping_interval(enpeer, UINT32_MAX/*ENET_PEER_PING_INTERVAL * 0xfffff*/); emit chan->m_sock->readyRead(); if (false) { ENetPacket *packet = enet_packet_create("hehehe123", 10, ENET_PACKET_FLAG_RELIABLE); enet_packet_resize(packet, 13); strcpy((char*)&packet->data[9], "foo"); uint8_t chanid = 0; // enet_peer_send(enpeer, chanid, packet); m_enpoll->sendPacket(enpeer, chanid, packet); } }
void CNetServerSession::SetLocalClient(bool isLocalClient) { m_IsLocalClient = isLocalClient; if (!isLocalClient) return; // Prevent the local client of the host from timing out too quickly #if (ENET_VERSION >= ENET_VERSION_CREATE(1, 3, 4)) enet_peer_timeout(m_Peer, 0, MAXIMUM_HOST_TIMEOUT, MAXIMUM_HOST_TIMEOUT); #endif }
void NetClient::Connect(const char* connect) { m_enetclient = enet_host_create(NULL, 1, 1, 350000, 95000); // This is 3 megabit d/l, .75 megabit upload. Should be the lowest common denominator of internet connection today. ENetAddress address; enet_address_set_host(&address, connect); address.port = 51072; m_enetpeer = enet_host_connect(m_enetclient, &address, 1, 0); #ifdef _DEBUG enet_peer_timeout(m_enetpeer, UINT32_MAX, UINT32_MAX, UINT32_MAX); #endif }
//Connect to a server bool Network::connect(const ENetAddress & addr) { if (m_connecting) return false; disconnect(); m_server = enet_host_connect(m_client, &addr, 2, 0); if (!m_server) return false; enet_peer_timeout(m_server, ENET_PEER_TIMEOUT_LIMIT, 500, 3000); m_connecting = true; return true; }
bool Client::connect(const char* address, unsigned int port) { m_client = enet_host_create(nullptr /* create a client host */, 1 /* only allow 1 outgoing connection */, 2 /* allow up 2 channels to be used, 0 and 1 */, 57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */, 14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */); Debug::assertf(m_client, "failed to create ENet client host"); enet_address_set_host(&m_address, address); m_address.port = port; m_peer = enet_host_connect(m_client, &m_address, 2, 0); if (Settings::instance()->startupFlags() & Settings::NoTimeoutStartupFlag) { enet_peer_timeout(m_peer, 0, 3600 * 1000, 3600 * 1000); } if (m_peer == NULL) { Debug::log(Debug::Area::NetworkClientInitialArea) << "Client failed to connect to server"; exit(EXIT_FAILURE); } ENetEvent event; if (enet_host_service(m_client, &event, 5000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT) { Debug::log(Debug::Area::NetworkClientInitialArea) << "Client connection to server succeeded!"; m_mainMenu->hideMainMenu(); m_chat = new ChatDialog(this, m_mainMenu); m_chat->show(); //NOTE: no world is created yet. we now wait for the server to receive our initial connection data, and give us back a //player id, which we then create as the main player and finally, create the world. m_connected = true; sendInitialConnectionData(); return true; } else { Debug::log(Debug::Area::NetworkClientInitialArea) << "Client connection to server failed!"; Debug::log(Debug::Area::NetworkClientInitialArea) << "Client failed to connect to server within timeout"; enet_peer_reset(m_peer); return false; } }
Client::Client() { mAddress.port = 6666; enet_address_set_host(&mAddress, "127.0.0.1"); mHost = enet_host_create(NULL, 32, 2, 0, 0); mServerPeer = enet_host_connect(mHost, &mAddress, 2, 0); enet_peer_timeout(mServerPeer, std::numeric_limits<int32_t>::max(), std::numeric_limits<int32_t>::max(), std::numeric_limits<int32_t>::max()); ENetEvent event; if (enet_host_service(mHost, &event, 5000)) { std::cout << "connected" << std::endl; } else { std::cout << "connection failed" << std::endl; } }
bool CNetClientSession::Connect(const CStr& server, const u16 port, const bool isLocalClient) { ENSURE(!m_Host); ENSURE(!m_Server); // Create ENet host ENetHost* host = enet_host_create(NULL, 1, CHANNEL_COUNT, 0, 0); if (!host) return false; // Bind to specified host ENetAddress addr; addr.port = port; if (enet_address_set_host(&addr, server.c_str()) < 0) return false; // Initiate connection to server ENetPeer* peer = enet_host_connect(host, &addr, CHANNEL_COUNT, 0); if (!peer) return false; m_Host = host; m_Server = peer; // Prevent the local client of the host from timing out too quickly. #if (ENET_VERSION >= ENET_VERSION_CREATE(1, 3, 4)) if (isLocalClient) enet_peer_timeout(peer, 1, MAXIMUM_HOST_TIMEOUT, MAXIMUM_HOST_TIMEOUT); #endif m_Stats = new CNetStatsTable(m_Server); if (CProfileViewer::IsInitialised()) g_ProfileViewer.AddRootTable(m_Stats); return true; }
void Tunneld::promiseChannelCleanup(ToxTunChannel *chan) { qDebug()<<chan<<sender(); QObject *snderobj = (QObject*)sender(); QTimer *repeat_timer = NULL; qDebug()<<snderobj->objectName()<<snderobj->metaObject()->className(); if (chan == NULL) { repeat_timer = (QTimer*)snderobj; assert(repeat_timer != NULL); int conid = repeat_timer->property("conid").toInt(); if (!m_conid_chans.contains(conid)) { qDebug()<<"maybe too late repeat check self sock close timer event"; repeat_timer->deleteLater(); return; } chan = m_conid_chans[conid]; assert(chan != NULL); } else { // snderobj is ENetPoll or QTcpSocket } QTcpSocket *sock = chan->m_sock; ENetPeer *enpeer = chan->m_enpeer; ////////// QHash<QString, bool> promise_results; promise_results["sock_closed"] = chan->sock_closed; // promise_results["enet_closed"] = chan->enet_closed; promise_results["peer_sock_closed"] = chan->peer_sock_closed; bool promise_result = true; for (auto it = promise_results.begin(); it != promise_results.end(); it ++) { QString key = it.key(); bool val = it.value(); promise_result = promise_result && val; } if (true) { // 检测对方最近的回包情况 if (!promise_result && repeat_timer == NULL && promise_results["peer_sock_closed"] && !promise_results["sock_closed"]) { qDebug()<<"here"; if (chan->last_recv_peer_pkt_time == QDateTime()) { qDebug()<<"maybe can close socket right now, because recv nothing forever"; } QTimer *t = new QTimer(); t->setInterval(500); t->setSingleShot(true); t->setProperty("conid", QVariant(chan->m_conid)); // // QObject::connect(t, &QTimer::timeout, this, &Tunneld::promiseChannelCleanup, Qt::QueuedConnection); QObject::connect(t, SIGNAL(timeout()), this, SLOT(promiseChannelCleanup()), Qt::QueuedConnection); qDebug()<<"start repeat check sock close timer:"; t->start(); } if (!promise_result && repeat_timer != NULL && promise_results["peer_sock_closed"] && !promise_results["sock_closed"]) { // QDateTime now_time = QDateTime::currentDateTime(); uint32_t last_recv_to_now_time = chan->last_recv_peer_pkt_time.msecsTo(now_time); qDebug()<<"here:"<<last_recv_to_now_time<<enpeer->lastReceiveTime; if (last_recv_to_now_time > 7000) { qDebug()<<"last recv to now, force close self socket:"<<last_recv_to_now_time <<enpeer->incomingPeerID<<enpeer->outgoingPeerID; // 不能直接关闭,要在当前函数执行完后,即下一次事件的时候开始执行。 QTimer::singleShot(1, sock, &QTcpSocket::close); // QTimer *t = new QTimer(); // t->setSingleShot(true); // QObject::connect(t, &QTimer::timeout, sock, &QTcpSocket::close, Qt::QueuedConnection); // t->start(1); repeat_timer->deleteLater(); } else { repeat_timer->start(); } } } if (!promise_result) { qDebug()<<"promise nooooot satisfied:"<<promise_results<<chan->m_conid; return; } chan->promise_close_time = QDateTime::currentDateTime(); qDebug()<<"promise satisfied."<<chan->m_conid; ///// do cleanup bool force_closed = chan->force_closed; // enpeer->toxchan = NULL; // cleanup peerRemoveChan(enpeer, chan); this->m_sock_chans.remove(sock); // this->m_enpeer_chans.remove(enpeer); this->m_conid_chans.remove(chan->m_conid); delete chan; sock->disconnect(); sock->deleteLater(); if (repeat_timer != NULL) repeat_timer->deleteLater(); qDebug()<<"curr chan size:"<<this->m_sock_chans.count()<<this->m_conid_chans.count(); if (force_closed) { return; } // 延时关闭enet_peer QTimer *t = new QTimer(); auto later_close_timeout = [enpeer, t]() { qDebug()<<enpeer<<enpeer->state; if (enpeer->state != ENET_PEER_STATE_CONNECTED) { qDebug()<<"warning, peer currently not connected:"<<enpeer->incomingPeerID; } if (! (enet_list_empty (& enpeer -> outgoingReliableCommands) && enet_list_empty (& enpeer -> outgoingUnreliableCommands) && enet_list_empty (& enpeer -> sentReliableCommands))) { qDebug()<<"warning, maybe has unsent packet:"<<enpeer->incomingPeerID; } qDebug()<<"last recv time:"<<enpeer->incomingPeerID <<enetx_time_diff(enpeer->lastReceiveTime, enet_time_get()); qDebug()<<"restore peer timeout, ping interval"; enet_peer_timeout(enpeer, ENET_PEER_TIMEOUT_LIMIT*2, ENET_PEER_TIMEOUT_MINIMUM*2, ENET_PEER_TIMEOUT_MAXIMUM*2); enet_peer_ping_interval(enpeer, ENET_PEER_PING_INTERVAL*2); // enet_peer_disconnect_now(enpeer, qrand()); enet_peer_disconnect_later(enpeer, qrand()); t->deleteLater(); }; qDebug()<<"last recv time:"<<enpeer->incomingPeerID <<enetx_time_diff(enpeer->lastReceiveTime, enet_time_get()); // QTimer::singleShot(5678, later_close_timeout); t->setInterval(5678); t->setSingleShot(true); QObject::connect(t, &QTimer::timeout, later_close_timeout); t->start(); }
void Tunnelc::onNewTcpConnection() { QTcpServer *tcpsrv = (QTcpServer*)sender(); QTcpSocket *sock = tcpsrv->nextPendingConnection(); int idx = this->m_tcpsrvs[tcpsrv]; ToxTunRecord rec = this->m_cfg->m_recs[idx]; QObject::connect(sock, &QTcpSocket::readyRead, this, &Tunnelc::onTcpReadyRead, Qt::QueuedConnection); QObject::connect(sock, &QTcpSocket::disconnected, this, &Tunnelc::onTcpDisconnected, Qt::QueuedConnection); //// channels QString friendId = "D62E57FCBDC04080C5F78875AB24DB2AE4C797B5C5A9AC69DB5924FD972E363AF2038D5B7A44"; friendId = rec.m_remote_pubkey; ToxTunChannel *chan = new ToxTunChannel(); chan->m_sock = sock; chan->m_enhost = m_encli; // chan->m_enpeer = peer; chan->m_peer_pubkey = friendId; chan->m_host = "127.0.0.1"; chan->m_port = rec.m_remote_port; chan->m_conid = nextConid(); // ENetAddress eaddr = {0}; enet_address_set_host(&eaddr, "127.0.0.1"); // tunip: 10.0.5.x eaddr.port = 7767; ENetPeer *peer = enet_host_connect(this->m_encli, &eaddr, 2, chan->m_port); if (peer == NULL) { qDebug()<<"error: can not connect to enet, maybe exceed max connection:" <<m_encli->peerCount<<enet_host_used_peer_size(m_encli); // cleanup and close socket // sock->disconnect(); // this->m_sock_chans.remove(sock); // sock->close(); } qDebug()<<peer<<peer->connectID <<"tol:"<<peer->timeoutLimit<<"tomin:"<<peer->timeoutMinimum <<"tomax:"<<peer->timeoutMaximum; // peer->timeoutLimit *= 10; // peer->timeoutMinimum *= 10; // peer->timeoutMaximum *= 10; enet_peer_timeout(peer, ENET_PEER_TIMEOUT_LIMIT, ENET_PEER_TIMEOUT_MINIMUM, ENET_PEER_TIMEOUT_MAXIMUM); enet_peer_ping_interval(peer, ENET_PEER_PING_INTERVAL); if (peerChansCount(peer) > 0) { qDebug()<<peer->incomingPeerID; ToxTunChannel *tchan = peerLastChan(peer); qDebug()<<tchan<<tchan->m_conid <<tchan->sock_closed<<tchan->peer_sock_closed<<tchan->enet_closed; // promiseChannelCleanup(tchan); // 无条件把相关联的chan清理掉 if (tchan->sock_closed == true && tchan->peer_sock_closed == false) { qDebug()<<"need force cleanup:"<<tchan->m_conid; tchan->peer_sock_closed = true; tchan->force_closed = true; promiseChannelCleanup(tchan); } else if (tchan->sock_closed == false && tchan->peer_sock_closed == false) { qDebug()<<"need force cleanup:"<<tchan->m_conid; tchan->peer_sock_closed = true; tchan->sock_closed = true; tchan->force_closed = true; promiseChannelCleanup(tchan); } assert(peerChansCount(peer) == 0); // assert(1 == 2); } peerAddChan(peer, chan); chan->m_enpeer = peer; this->m_sock_chans[sock] = chan; // this->m_enpeer_chans[peer] = chan; this->m_conid_chans[chan->m_conid] = chan; }