2010-02-18 7 views
1

내 질문은 this post과 비슷하지만 IIS, ASP.NET 및 C#을 사용하여 동일한 작업을 수행해야합니다.웹 클라이언트가 파일을 성공적으로 수신했음을 감지하는 방법은 무엇입니까?

클래스의 메소드 중 어느 것도 데이터가 전송되었거나 보내지지 않은 경우 피드백을 제공하지 않으므로 TransmitFile()은 그 작업을 수행하는지 (알 수 없음) 결과를 알 수있는 방법을 제공하지 않습니다.

나는 .Filter 속성을 사용하려고 생각했지만 필터는 피드백을 제공하지 않는 HttpResponseStream을 기반으로합니다.

아이디어가 있으십니까?

+0

오류가 발생해도 예외가 발생하지 않습니까? –

답변

0

Response.IsClientConnected을 확인한 후 TransmitFile으로 전화하십시오.

+0

아니요, "writer"함수 중 어느 것도 예외를 throw하지 않습니다. 클라이언트가 여전히 청취 중인지를 알 수있는 유일한 방법은 아래에 설명 된대로 Response.IsClientConnected를 사용하는 것입니다. –

1

몇 가지 테스트를 마친 후에 문제에 대한 다음 해결책을 찾았습니다. TransmitFile()에는 하나의 심각한 제한이 있습니다. 전송하기 전에 전체 파일을 메모리로 읽어들입니다. 이것은 대용량 파일의 경우 매우 나쁩니다. 그래서 기본적으로 클라이언트가 각 청크 다음에 연결되어 있으면 수동으로 청킹 및 확인합니다.

context.Response.Clear(); 
context.Response.BufferOutput = false; 
context.Response.ContentType = "application/octet-stream"; 
context.Response.AddHeader("Content-Disposition", "attachment; filename=" + originalFilename); 
context.Response.AddHeader("Content-Length", fileLength.ToString()); 
context.Response.Cache.SetNoStore(); 

context.Response.Flush(); 

downloadFailed = !context.Response.IsClientConnected; 

int thisChunk; 
long offset = 0; 
int chunkSize = 1024 * 8; 
byte[] bytes = new byte[chunkSize]; 

FileStream r = File.OpenRead(localFilename); 

while((offset < fileLength) && !downloadFailed) 
{ 
    if((fileLength - offset) < chunkSize) 
    { 
     thisChunk = (int)(fileLength - offset); 
    } 
    else 
    { 
     thisChunk = chunkSize; 
    } 

    r.Read(bytes, 0, chunkSize); 

    try 
    { 
     context.Response.BinaryWrite(bytes); 
     context.Response.Flush(); 

     if(!context.Response.IsClientConnected) 
     { 
      downloadFailed = true; 
     } 
    } 
    catch(ObjectDisposedException ex1) 
    { 
     // Stream is closed, nothing written 
     break; 
    } 
    catch(System.IO.IOException ex3) 
    { 
     // I/O error, unknown state, abort 
     Trace.Write(ex3); 
     break; 
    } 

    offset += thisChunk; 
} 

if(!downloadFailed) 
{ 
    // now update the file, statistics, etc 
} 

context.Response.Flush(); 

HttpContext.Current.ApplicationInstance.CompleteRequest(); 

최적 크기를 찾으려면 청크 크기로 비트를 재생해야합니다. 하지만 기본적으로이 기능은 안정적으로 작동합니다.

관련 문제