📄 core.cpp
字号:
WaitForSingleObject(m_SendBlockCond, DWORD(m_iSndTimeOut)); #endif // check the connection status if (m_bBroken || m_bClosing) throw CUDTException(2, 1, 0); else if (!m_bConnected) throw CUDTException(2, 2, 0); } } if (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize()) return 0; int size = (m_iSndBufSize - m_pSndBuffer->getCurrBufSize()) * m_iPayloadSize; if (size > len) size = len; // insert the user buffer into the sening list m_pSndBuffer->addBuffer(data, size); // insert this socket to snd list if it is not on the list yet m_pSndQueue->m_pSndUList->update(this, false); return size;}int CUDT::recv(char* data, const int& len){ if (UDT_DGRAM == m_iSockType) throw CUDTException(5, 10, 0); CGuard recvguard(m_RecvLock); // throw an exception if not connected if (!m_bConnected) throw CUDTException(2, 2, 0); else if ((m_bBroken || m_bClosing) && (0 == m_pRcvBuffer->getRcvDataSize())) throw CUDTException(2, 1, 0); if (len <= 0) return 0; if (0 == m_pRcvBuffer->getRcvDataSize()) { if (!m_bSynRecving) throw CUDTException(6, 2, 0); else { #ifndef WIN32 pthread_mutex_lock(&m_RecvDataLock); if (m_iRcvTimeOut < 0) { while (!m_bBroken && m_bConnected && !m_bClosing && (0 == m_pRcvBuffer->getRcvDataSize())) pthread_cond_wait(&m_RecvDataCond, &m_RecvDataLock); } else { uint64_t exptime = CTimer::getTime() + m_iRcvTimeOut * 1000ULL; timespec locktime; locktime.tv_sec = exptime / 1000000; locktime.tv_nsec = (exptime % 1000000) * 1000; pthread_cond_timedwait(&m_RecvDataCond, &m_RecvDataLock, &locktime); } pthread_mutex_unlock(&m_RecvDataLock); #else if (m_iRcvTimeOut < 0) { while (!m_bBroken && m_bConnected && !m_bClosing && (0 == m_pRcvBuffer->getRcvDataSize())) WaitForSingleObject(m_RecvDataCond, INFINITE); } else WaitForSingleObject(m_RecvDataCond, DWORD(m_iRcvTimeOut)); #endif } } // throw an exception if not connected if (!m_bConnected) throw CUDTException(2, 2, 0); else if ((m_bBroken || m_bClosing) && (0 == m_pRcvBuffer->getRcvDataSize())) throw CUDTException(2, 1, 0); return m_pRcvBuffer->readBuffer(data, len);}int CUDT::sendmsg(const char* data, const int& len, const int& msttl, const bool& inorder){ if (UDT_STREAM == m_iSockType) throw CUDTException(5, 9, 0); CGuard sendguard(m_SendLock); // throw an exception if not connected if (m_bBroken || m_bClosing) throw CUDTException(2, 1, 0); else if (!m_bConnected) throw CUDTException(2, 2, 0); if (len <= 0) return 0; if (len > m_iSndBufSize * m_iPayloadSize) throw CUDTException(5, 12, 0); if ((m_iSndBufSize - m_pSndBuffer->getCurrBufSize()) * m_iPayloadSize < len) { if (!m_bSynSending) throw CUDTException(6, 1, 0); else { // wait here during a blocking sending #ifndef WIN32 pthread_mutex_lock(&m_SendBlockLock); if (m_iSndTimeOut < 0) { while (!m_bBroken && m_bConnected && !m_bClosing && ((m_iSndBufSize - m_pSndBuffer->getCurrBufSize()) * m_iPayloadSize < len)) pthread_cond_wait(&m_SendBlockCond, &m_SendBlockLock); } else { uint64_t exptime = CTimer::getTime() + m_iSndTimeOut * 1000ULL; timespec locktime; locktime.tv_sec = exptime / 1000000; locktime.tv_nsec = (exptime % 1000000) * 1000; pthread_cond_timedwait(&m_SendBlockCond, &m_SendBlockLock, &locktime); } pthread_mutex_unlock(&m_SendBlockLock); #else if (m_iSndTimeOut < 0) { while (!m_bBroken && m_bConnected && !m_bClosing && ((m_iSndBufSize - m_pSndBuffer->getCurrBufSize()) * m_iPayloadSize < len)) WaitForSingleObject(m_SendBlockCond, INFINITE); } else WaitForSingleObject(m_SendBlockCond, DWORD(m_iSndTimeOut)); #endif // check the connection status if (m_bBroken || m_bClosing) throw CUDTException(2, 1, 0); else if (!m_bConnected) throw CUDTException(2, 2, 0); } } if ((m_iSndBufSize - m_pSndBuffer->getCurrBufSize()) * m_iPayloadSize < len) return 0; // insert the user buffer into the sening list m_pSndBuffer->addBuffer(data, len, msttl, inorder); // insert this socket to the snd list if it is not on the list yet m_pSndQueue->m_pSndUList->update(this, false); return len; }int CUDT::recvmsg(char* data, const int& len){ if (UDT_STREAM == m_iSockType) throw CUDTException(5, 9, 0); CGuard recvguard(m_RecvLock); // throw an exception if not connected if (!m_bConnected) throw CUDTException(2, 2, 0); if (len <= 0) return 0; if (m_bBroken || m_bClosing) { int res = m_pRcvBuffer->readMsg(data, len); if (0 == res) throw CUDTException(2, 1, 0); else return res; } if (!m_bSynRecving) { int res = m_pRcvBuffer->readMsg(data, len); if (0 == res) throw CUDTException(6, 2, 0); else return res; } int res = 0; bool timeout = false; do { #ifndef WIN32 pthread_mutex_lock(&m_RecvDataLock); if (m_iRcvTimeOut < 0) { while (!m_bBroken && m_bConnected && !m_bClosing && (0 == (res = m_pRcvBuffer->readMsg(data, len)))) pthread_cond_wait(&m_RecvDataCond, &m_RecvDataLock); } else { uint64_t exptime = CTimer::getTime() + m_iRcvTimeOut * 1000ULL; timespec locktime; locktime.tv_sec = exptime / 1000000; locktime.tv_nsec = (exptime % 1000000) * 1000; if (pthread_cond_timedwait(&m_RecvDataCond, &m_RecvDataLock, &locktime) == ETIMEDOUT) timeout = true; res = m_pRcvBuffer->readMsg(data, len); } pthread_mutex_unlock(&m_RecvDataLock); #else if (m_iRcvTimeOut < 0) { while (!m_bBroken && m_bConnected && !m_bClosing && (0 == (res = m_pRcvBuffer->readMsg(data, len)))) WaitForSingleObject(m_RecvDataCond, INFINITE); } else { if (WaitForSingleObject(m_RecvDataCond, DWORD(m_iRcvTimeOut)) == WAIT_TIMEOUT) timeout = true; res = m_pRcvBuffer->readMsg(data, len); } #endif if (m_bBroken || m_bClosing) throw CUDTException(2, 1, 0); else if (!m_bConnected) throw CUDTException(2, 2, 0); } while ((0 == res) && !timeout); return res;}int64_t CUDT::sendfile(ifstream& ifs, const int64_t& offset, const int64_t& size, const int& block){ if (UDT_DGRAM == m_iSockType) throw CUDTException(5, 10, 0); CGuard sendguard(m_SendLock); if (m_bBroken || m_bClosing) throw CUDTException(2, 1, 0); else if (!m_bConnected) throw CUDTException(2, 2, 0); if (size <= 0) return 0; int64_t tosend = size; int unitsize; // positioning... try { ifs.seekg((streamoff)offset); } catch (...) { throw CUDTException(4, 1); } // sending block by block while (tosend > 0) { if (ifs.bad() || ifs.fail() || ifs.eof()) break; unitsize = int((tosend >= block) ? block : tosend); #ifndef WIN32 pthread_mutex_lock(&m_SendBlockLock); while (!m_bBroken && m_bConnected && !m_bClosing && (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize())) pthread_cond_wait(&m_SendBlockCond, &m_SendBlockLock); pthread_mutex_unlock(&m_SendBlockLock); #else while (!m_bBroken && m_bConnected && !m_bClosing && (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize())) WaitForSingleObject(m_SendBlockCond, INFINITE); #endif if (m_bBroken || m_bClosing) throw CUDTException(2, 1, 0); else if (!m_bConnected) throw CUDTException(2, 2, 0); tosend -= m_pSndBuffer->addBufferFromFile(ifs, unitsize); // insert this socket to snd list if it is not on the list yet m_pSndQueue->m_pSndUList->update(this, false); } return size - tosend;}int64_t CUDT::recvfile(ofstream& ofs, const int64_t& offset, const int64_t& size, const int& block){ if (UDT_DGRAM == m_iSockType) throw CUDTException(5, 10, 0); CGuard recvguard(m_RecvLock); if (!m_bConnected) throw CUDTException(2, 2, 0); else if ((m_bBroken || m_bClosing) && (0 == m_pRcvBuffer->getRcvDataSize())) throw CUDTException(2, 1, 0); if (size <= 0) return 0; int64_t torecv = size; int unitsize = block; int recvsize; // positioning... try { ofs.seekp((streamoff)offset); } catch (...) { throw CUDTException(4, 3); } // receiving... "recvfile" is always blocking while (torecv > 0) { if (ofs.bad() || ofs.fail()) break; #ifndef WIN32 pthread_mutex_lock(&m_RecvDataLock); while (!m_bBroken && m_bConnected && !m_bClosing && (0 == m_pRcvBuffer->getRcvDataSize())) pthread_cond_wait(&m_RecvDataCond, &m_RecvDataLock); pthread_mutex_unlock(&m_RecvDataLock); #else while (!m_bBroken && m_bConnected && !m_bClosing && (0 == m_pRcvBuffer->getRcvDataSize())) WaitForSingleObject(m_RecvDataCond, INFINITE); #endif if (!m_bConnected) throw CUDTException(2, 2, 0); else if ((m_bBroken || m_bClosing) && (0 == m_pRcvBuffer->getRcvDataSize())) throw CUDTException(2, 1, 0); unitsize = int((torecv >= block) ? block : torecv); recvsize = m_pRcvBuffer->readBufferToFile(ofs, unitsize); torecv -= recvsize; } return size - torecv;}void CUDT::sample(CPerfMon* perf, bool clear){ if (!m_bConnected) throw CUDTException(2, 2, 0); if (m_bBroken || m_bClosing) throw CUDTException(2, 1, 0); uint64_t currtime = CTimer::getTime(); perf->msTimeStamp = (currtime - m_StartTime) / 1000; m_llSentTotal += m_llTraceSent; m_llRecvTotal += m_llTraceRecv; m_iSndLossTotal += m_iTraceSndLoss; m_iRcvLossTotal += m_iTraceRcvLoss; m_iRetransTotal += m_iTraceRetrans; m_iSentACKTotal += m_iSentACK; m_iRecvACKTotal += m_iRecvACK; m_iSentNAKTotal += m_iSentNAK; m_iRecvNAKTotal += m_iRecvNAK; perf->pktSentTotal = m_llSentTotal; perf->pktRecvTotal = m_llRecvTotal; perf->pktSndLossTotal = m_iSndLossTotal; perf->pktRcvLossTotal = m_iRcvLossTotal; perf->pktRetransTotal = m_iRetransTotal; perf->pktSentACKTotal = m_iSentACKTotal; perf->pktRecvACKTotal = m_iRecvACKTotal; perf->pktSentNAKTotal = m_iSentNAKTotal; perf->pktRecvNAKTotal = m_iRecvNAKTotal; perf->pktSent = m_llTraceSent; perf->pktRecv = m_llTraceRecv; perf->pktSndLoss = m_iTraceSndLoss; perf->pktRcvLoss = m_iTraceRcvLoss; perf->pktRetrans = m_iTraceRetrans; perf->pktSentACK = m_iSentACK; perf->pktRecvACK = m_iRecvACK; perf->pktSentNAK = m_iSentNAK; perf->pktRecvNAK = m_iRecvNAK; double interval = double(currtime - m_LastSampleTime); perf->mbpsSendRate = double(m_llTraceSent) * m_iPayloadSize * 8.0 / interval; perf->mbpsRecvRate = double(m_llTraceRecv) * m_iPayloadSize * 8.0 / interval; perf->usPktSndPeriod = m_ullInterval / double(m_ullCPUFrequency); perf->pktFlowWindow = m_iFlowWindowSize; perf->pktCongestionWindow = (int)m_dCongestionWindow; perf->pktFlightSize = CSeqNo::seqlen(const_cast<int32_t&>(m_iSndLastAck), m_iSndCurrSeqNo); perf->msRTT = m_iRTT/1000.0; perf->mbpsBandwidth = m_iBandwidth * m_iPayloadSize * 8.0 / 1000000.0; #ifndef WIN32 if (0 == pthread_mutex_trylock(&m_ConnectionLock)) #else if (WAIT_OBJECT_0 == WaitForSingleObject(m_ConnectionLock, 0)) #endif { perf->byteAvailSndBuf = (NULL == m_pSndBuffer) ? 0 : m_iSndBufSize - m_pSndBuffer->getCurrBufSize(); perf->byteAvailRcvBuf = (NULL == m_pRcvBuffer) ? 0 : m_pRcvBuffer->getAvailBufSize(); #ifndef WIN32 pthread_mutex_unlock(&m_ConnectionLock); #else ReleaseMutex(m_ConnectionLock); #endif } else { perf->byteAvailSndBuf = 0; perf->byteAvailRcvBuf = 0; } if (clear) { m_llTraceSent = m_llTraceRecv = m_iTraceSndLoss = m_iTraceSndLoss = m_iTraceRetrans = m_iSentACK = m_iRecvACK = m_iSentNAK = m_iRecvNAK = 0; m_LastSampleTime = currtime; }}void CUDT::initSynch(){ #ifndef WIN32 pthread_mutex_init(&m_SendBlockLock, NULL); pthread_cond_init(&m_SendBlockCond, NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -