예제 #1
0
파일: CUDT.cs 프로젝트: Wiladams/NewTOAPIA
      // 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;
}