// Functionality: // Request UDT to send out a file described as "fd", starting from "offset", with size of "size". // Parameters: // 0) [in] ifs: The input file stream. // 1) [in] offset: From where to read and send data; // 2) [in] size: How many data to be sent. // 3) [in] block: size of block per read from disk // Returned value: // Actual size of data sent. public Int64 sendfile(Stream ifs, Int64 offset, Int64 size, int block) { if (UDT_DGRAM == m_iSockType) throw new CUDTException(5, 10, 0); if (m_bBroken || m_bClosing) throw new CUDTException(2, 1, 0); else if (!m_bConnected) throw new CUDTException(2, 2, 0); if (size <= 0) return 0; CGuard sendguard = new CGuard(m_SendLock); long tosend = size; int unitsize; // positioning... try { ifs.seekg((streamoff)offset); } catch (Exception e) { throw new CUDTException(4, 1); } // sending block by block while (tosend > 0) { if (ifs.bad() || ifs.fail() || ifs.eof()) break; unitsize = (int)((tosend >= block) ? block : tosend); while (!m_bBroken && m_bConnected && !m_bClosing && (m_iSndBufSize <= m_pSndBuffer.getCurrBufSize())) WaitForSingleObject(m_SendBlockCond, INFINITE); if (m_bBroken || m_bClosing) throw new CUDTException(2, 1, 0); else if (!m_bConnected) throw new CUDTException(2, 2, 0); // record total time used for sending if (0 == m_pSndBuffer.getCurrBufSize()) m_llSndDurationCounter = CClock.getTime(); 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; }