int CSndUList::pop(sockaddr*& addr, CPacket& pkt) { CGuard listguard(m_ListLock); if (-1 == m_iLastEntry) return -1; // no pop until the next schedulled time uint64_t ts; CTimer::rdtsc(ts); if (ts < m_pHeap[0]->m_llTimeStamp) return -1; CUDT* u = m_pHeap[0]->m_pUDT; remove_(u); if (!u->m_bConnected || u->m_bBroken) return -1; // pack a packet from the socket if (u->packData(pkt, ts) <= 0) return -1; addr = u->m_pPeerAddr; // insert a new entry, ts is the next processing time if (ts > 0) insert_(ts, u); return 1; }
const CPerfMon* CCC::getPerfInfo() { try { CUDT* u = CUDT::getUDTHandle(m_UDT); if (NULL != u) u->sample(&m_PerfInfo, false); } catch (...) { return NULL; } return &m_PerfInfo; }
int CUDT::p2p_send(const UDTSOCKET u, const char* peername, const char* buf, int len) { try { CUDT* udt = s_UDTUnited.lookup(u); return udt->send(buf, len); } catch (...) { return INVALID_SOCK; } }
int CUDT::send(UDTSOCKET u, const char* buf, int len, int flags) { try { CUDT* udt = s_UDTUnited.lookup(u); return udt->send(buf, len); } catch (...) { return INVALID_SOCK; } }
UDTSOCKET CUDT::p2pConnect(const char* peername) { try { UDTSOCKET u = s_UDTUnited.newSocket(AF_INET, SOCK_STREAM); CUDT* udt = s_UDTUnited.lookup(u); return udt->p2pConnect(u, peername, s_UDTUnited.m_p2ph); } catch (...) { return INVALID_SOCK; } }
DWORD WINAPI CSndQueue::worker(LPVOID param) #endif { CSndQueue* self = (CSndQueue*)param; CPacket pkt; while (!self->m_bClosing) { uint64_t ts = self->m_pSndUList->getNextProcTime(); if (ts > 0) { // wait until next processing time of the first socket on the list uint64_t currtime; CTimer::rdtsc(currtime); if (currtime < ts) self->m_pTimer->sleepto(ts); // it is time to process it, pop it out/remove from the list CUDT* u = self->m_pSndUList->pop(); if ((NULL == u) || !u->m_bConnected || u->m_bBroken) continue; // pack a packet from the socket uint64_t ts; if (u->packData(pkt, ts) > 0) self->m_pChannel->sendto(u->m_pPeerAddr, pkt); // insert a new entry, ts is the next processing time if (ts > 0) self->m_pSndUList->insert(ts, u); } else { // wait here if there is no sockets with data to be sent #ifndef WIN32 pthread_mutex_lock(&self->m_WindowLock); if (!self->m_bClosing && (self->m_pSndUList->m_iLastEntry < 0)) pthread_cond_wait(&self->m_WindowCond, &self->m_WindowLock); pthread_mutex_unlock(&self->m_WindowLock); #else WaitForSingleObject(self->m_WindowCond, INFINITE); #endif } } return NULL; }
int64_t CUDT::recvfile(UDTSOCKET u, fstream& ofs, const int64_t& offset, const int64_t& size, const int& block) { try { CUDT* udt = s_UDTUnited.lookup(u); return udt->recvfile(ofs, offset, size, block); } catch (CUDTException e) { s_UDTUnited.setError(new CUDTException(e)); return ERROR; } catch (...) { s_UDTUnited.setError(new CUDTException(-1, 0, 0)); return ERROR; } }
int CUDT::recvmsg(UDTSOCKET u, char* buf, int len) { try { CUDT* udt = s_UDTUnited.lookup(u); return udt->recvmsg(buf, len); } catch (CUDTException e) { s_UDTUnited.setError(new CUDTException(e)); return ERROR; } catch (...) { s_UDTUnited.setError(new CUDTException(-1, 0, 0)); return ERROR; } }
int CUDT::perfmon(UDTSOCKET u, CPerfMon* perf, bool clear) { try { CUDT* udt = s_UDTUnited.lookup(u); udt->sample(perf, clear); return 0; } catch (CUDTException e) { s_UDTUnited.setError(new CUDTException(e)); return ERROR; } catch (...) { s_UDTUnited.setError(new CUDTException(-1, 0, 0)); return ERROR; } }
int CUDT::setsockopt(UDTSOCKET u, int, UDTOpt optname, const void* optval, int optlen) { try { CUDT* udt = s_UDTUnited.lookup(u); udt->setOpt(optname, optval, optlen); return 0; } catch (CUDTException e) { s_UDTUnited.setError(new CUDTException(e)); return ERROR; } catch (...) { s_UDTUnited.setError(new CUDTException(-1, 0, 0)); return ERROR; } }
int CUDT::sendmsg(UDTSOCKET u, const char* buf, int len, int ttl, bool inorder) { try { CUDT* udt = s_UDTUnited.lookup(u); return udt->sendmsg((char*)buf, len, ttl, inorder); } catch (CUDTException e) { s_UDTUnited.setError(new CUDTException(e)); return ERROR; } catch (bad_alloc&) { s_UDTUnited.setError(new CUDTException(3, 2, 0)); return ERROR; } catch (...) { s_UDTUnited.setError(new CUDTException(-1, 0, 0)); return ERROR; } }
void recethread::run() { if (m_iFolder == 0) { //udt = new CUDT(); //connect(udt,SIGNAL(sendProgress(qint64,qint64)),this,SLOT(onSendProgress(qint64,qint64))); // get size information int iContent = 3; char content[iContent+1]; if (UDT::ERROR == UDT::recv(m_handle, content, iContent, 0)) { qDebug() << "recv: " << UDT::getlasterror().getErrorMessage() << endl; return ; } else { qDebug()<< "receive file or directory request success"; content[iContent] = '\0'; char *strContent = new char[iContent+1]; memset(strContent,0,iContent+1); memcpy(strContent, content, iContent); if (0 == strcmp(strContent, "FCS")) { qDebug() << "receive FCS"; } else { return; } } if (UDT::ERROR == UDT::recv(m_handle, (char*)&size, sizeof(uint64_t), 0)) { qDebug() << "handle: " << m_handle; qDebug() << "send: " << UDT::getlasterror().getErrorMessage() << endl; //qDebug() << "receive file size success"; return; } if (size < 0) { return; } qDebug() << "receive file size : " << size; std::fstream ofs(m_strFileName.toStdString().c_str(), std::ios::out | std::ios::binary | std::ios::trunc); int64_t recvsize; int64_t offset = 0; CUDT *udt = CUDT::getUdt(m_handle); udt->setFolderSize(size); connect(udt,SIGNAL(sendProgress(qint64,double)),this,SLOT(onSendProgress(qint64,double))); if (UDT::ERROR == (recvsize = udt->recvfile(ofs, offset, size))) { QString str = UDT::getlasterror().getErrorMessage(); //cout << "recvfile: " << UDT::getlasterror().getErrorMessage() << endl; //return -1; } emit sendSuccess(); UDT::close(m_handle); ofs.close(); }
DWORD WINAPI CRcvQueue::worker(LPVOID param) #endif { CRcvQueue* self = (CRcvQueue*)param; sockaddr* addr = (AF_INET == self->m_UnitQueue.m_iIPversion) ? (sockaddr*) new sockaddr_in : (sockaddr*) new sockaddr_in6; CUDT* u = NULL; int32_t id; while (!self->m_bClosing) { #ifdef NO_BUSY_WAITING self->m_pTimer->tick(); #endif // check waiting list, if new socket, insert it to the list while (self->ifNewEntry()) { CUDT* ne = self->getNewEntry(); if (NULL != ne) { self->m_pRcvUList->insert(ne); self->m_pHash->insert(ne->m_SocketID, ne); } } // find next available slot for incoming packet CUnit* unit = self->m_UnitQueue.getNextAvailUnit(); if (NULL == unit) { // no space, skip this packet CPacket temp; temp.m_pcData = new char[self->m_iPayloadSize]; temp.setLength(self->m_iPayloadSize); self->m_pChannel->recvfrom(addr, temp); delete [] temp.m_pcData; goto TIMER_CHECK; } unit->m_Packet.setLength(self->m_iPayloadSize); // reading next incoming packet, recvfrom returns -1 is nothing has been received if (self->m_pChannel->recvfrom(addr, unit->m_Packet) < 0) goto TIMER_CHECK; id = unit->m_Packet.m_iID; // ID 0 is for connection request, which should be passed to the listening socket or rendezvous sockets if (0 == id) { if (NULL != self->m_pListener) self->m_pListener->listen(addr, unit->m_Packet); else if (NULL != (u = self->m_pRendezvousQueue->retrieve(addr, id))) { // asynchronous connect: call connect here // otherwise wait for the UDT socket to retrieve this packet if (!u->m_bSynRecving) u->connect(unit->m_Packet); else self->storePkt(id, unit->m_Packet.clone()); } } else if (id > 0) { if (NULL != (u = self->m_pHash->lookup(id))) { if (CIPAddress::ipcmp(addr, u->m_pPeerAddr, u->m_iIPversion)) { if (u->m_bConnected && !u->m_bBroken && !u->m_bClosing) { if (0 == unit->m_Packet.getFlag()) u->processData(unit); else u->processCtrl(unit->m_Packet); u->checkTimers(); self->m_pRcvUList->update(u); } else{//cout<<"CCBroken"<<endl; } } } else if (NULL != (u = self->m_pRendezvousQueue->retrieve(addr, id))) { if (!u->m_bSynRecving) u->connect(unit->m_Packet); else self->storePkt(id, unit->m_Packet.clone()); } else { //cout<<"CCBroekn"<<endl; } } TIMER_CHECK: // take care of the timing event for all UDT sockets uint64_t currtime; CTimer::rdtsc(currtime); CRNode* ul = self->m_pRcvUList->m_pUList; #ifdef INCAST uint64_t ctime = currtime - 1000 * CTimer::getCPUFrequency(); #else uint64_t ctime = currtime - 10000 * CTimer::getCPUFrequency(); #endif while ((NULL != ul) && (ul->m_llTimeStamp < ctime)) { CUDT* u = ul->m_pUDT; if (u->m_bConnected && !u->m_bBroken && !u->m_bClosing) { u->checkTimers(); self->m_pRcvUList->update(u); } else { // the socket must be removed from Hash table first, then RcvUList self->m_pHash->remove(u->m_SocketID); self->m_pRcvUList->remove(u); u->m_pRNode->m_bOnList = false; } ul = self->m_pRcvUList->m_pUList; } // Check connection requests status for all sockets in the RendezvousQueue. self->m_pRendezvousQueue->updateConnStatus(); } if (AF_INET == self->m_UnitQueue.m_iIPversion) delete (sockaddr_in*)addr; else delete (sockaddr_in6*)addr; #ifndef WIN32 return NULL; #else SetEvent(self->m_ExitCond); return 0; #endif }
DWORD WINAPI CRcvQueue::worker(LPVOID param) #endif { CRcvQueue* self = (CRcvQueue*)param; CUnit temp; temp.m_Packet.m_pcData = new char[self->m_iPayloadSize]; sockaddr* addr = (AF_INET == self->m_UnitQueue.m_iIPversion) ? (sockaddr*) new sockaddr_in : (sockaddr*) new sockaddr_in6; while (!self->m_bClosing) { #ifdef NO_BUSY_WAITING self->m_pTimer->tick(); #endif // check waiting list, if new socket, insert it to the list if (self->ifNewEntry()) { CUDT* ne = self->getNewEntry(); if (NULL != ne) { self->m_pRcvUList->insert(ne); self->m_pHash->insert(ne->m_SocketID, ne); } } // find next available slot for incoming packet CUnit* unit = self->m_UnitQueue.getNextAvailUnit(); if (NULL == unit) unit = &temp; unit->m_Packet.setLength(self->m_iPayloadSize); CUDT* u = NULL; int32_t id; // reading next incoming packet if (self->m_pChannel->recvfrom(addr, unit->m_Packet) <= 0) goto TIMER_CHECK; if (unit == &temp) goto TIMER_CHECK; id = unit->m_Packet.m_iID; // ID 0 is for connection request, which should be passed to the listening socket or rendezvous sockets if (0 == id) { if (NULL != self->m_pListener) ((CUDT*)self->m_pListener)->listen(addr, unit->m_Packet); else if (self->m_pRendezvousQueue->retrieve(addr, id, ((CHandShake*)unit->m_Packet.m_pcData)->m_iID, u)) { if (u->m_bConnected && !u->m_bBroken) u->processCtrl(unit->m_Packet); else self->storePkt(id, unit->m_Packet.clone()); } } else if (id > 0) { if (NULL != (u = self->m_pHash->lookup(id))) { if (u->m_bConnected && !u->m_bBroken) { if (0 == unit->m_Packet.getFlag()) u->processData(unit); else u->processCtrl(unit->m_Packet); u->checkTimers(); self->m_pRcvUList->update(u); } } else self->storePkt(id, unit->m_Packet.clone()); } TIMER_CHECK: // take care of the timing event for all UDT sockets CRNode* ul = self->m_pRcvUList->m_pUList; uint64_t currtime; CTimer::rdtsc(currtime); uint64_t ctime = currtime - 100000 * CTimer::getCPUFrequency(); while ((NULL != ul) && (ul->m_llTimeStamp < ctime)) { CUDT* u = ul->m_pUDT; u->checkTimers(); if (u->m_bConnected && !u->m_bBroken) self->m_pRcvUList->update(u); else { // the socket must be removed from Hash table first, then RcvUList self->m_pHash->remove(u->m_SocketID); self->m_pRcvUList->remove(u); } ul = self->m_pRcvUList->m_pUList; } } delete [] temp.m_Packet.m_pcData; if (AF_INET == self->m_UnitQueue.m_iIPversion) delete (sockaddr_in*)addr; else delete (sockaddr_in6*)addr; return NULL; }